diff --git a/kong/plugins/oidc/handler.lua b/kong/plugins/oidc/handler.lua index 07f05af5..53bd2c7f 100644 --- a/kong/plugins/oidc/handler.lua +++ b/kong/plugins/oidc/handler.lua @@ -4,6 +4,10 @@ local utils = require("kong.plugins.oidc.utils") local filter = require("kong.plugins.oidc.filter") local session = require("kong.plugins.oidc.session") +local singletons = require "kong.singletons" +local constants = require "kong.constants" +local responses = require "kong.tools.responses" + OidcHandler.PRIORITY = 1000 @@ -13,6 +17,13 @@ end function OidcHandler:access(config) OidcHandler.super.access(self) + + if ngx.ctx.authenticated_credential and config.anonymous ~= "" then + -- we're already authenticated, and we're configured for using anonymous, + -- hence we're in a logical OR between auth methods and we're already done. + return + end + local oidcConfig = utils.get_options(config, ngx) if filter.shouldProcessRequest(oidcConfig) then @@ -58,7 +69,20 @@ function make_oidc(oidcConfig) ngx.log(ngx.DEBUG, "Entering recovery page: " .. oidcConfig.recovery_page_path) ngx.redirect(oidcConfig.recovery_page_path) end - utils.exit(500, err, ngx.HTTP_INTERNAL_SERVER_ERROR) + if oidcConfig.anonymous ~= "" then + -- get anonymous user + local consumer_cache_key = singletons.db.consumers:cache_key(oidcConfig.anonymous) + local consumer, err = singletons.cache:get(consumer_cache_key, nil, + load_consumer_into_memory, + oidcConfig.anonymous, true) + if err then + return responses.send_HTTP_INTERNAL_SERVER_ERROR(err) + end + set_consumer(consumer, nil, nil) + + else + utils.exit(500, err, ngx.HTTP_INTERNAL_SERVER_ERROR) + end end return res end @@ -69,7 +93,21 @@ function introspect(oidcConfig) if err then if oidcConfig.bearer_only == "yes" then ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. oidcConfig.realm .. '",error="' .. err .. '"' - utils.exit(ngx.HTTP_UNAUTHORIZED, err, ngx.HTTP_UNAUTHORIZED) + if oidcConfig.anonymous ~= "" then + -- get anonymous user + local consumer_cache_key = singletons.db.consumers:cache_key(oidcConfig.anonymous) + local consumer, err = singletons.cache:get(consumer_cache_key, nil, + load_consumer_into_memory, + oidcConfig.anonymous, true) + if err then + return responses.send_HTTP_INTERNAL_SERVER_ERROR(err) + end + set_consumer(consumer, nil, nil) + + else + utils.exit(ngx.HTTP_UNAUTHORIZED, err, ngx.HTTP_UNAUTHORIZED) + end + end return nil end @@ -79,5 +117,23 @@ function introspect(oidcConfig) return nil end +-- TESTING + +local function set_consumer(consumer, credential, token) + ngx_set_header(constants.HEADERS.CONSUMER_ID, consumer.id) + ngx_set_header(constants.HEADERS.CONSUMER_CUSTOM_ID, consumer.custom_id) + ngx_set_header(constants.HEADERS.CONSUMER_USERNAME, consumer.username) + ngx.ctx.authenticated_consumer = consumer + if credential then + ngx_set_header("x-authenticated-scope", token.scope) + ngx_set_header("x-authenticated-userid", token.authenticated_userid) + ngx.ctx.authenticated_credential = credential + ngx_set_header(constants.HEADERS.ANONYMOUS, nil) -- in case of auth plugins concatenation + else + ngx_set_header(constants.HEADERS.ANONYMOUS, true) + end + +end + return OidcHandler diff --git a/kong/plugins/oidc/schema.lua b/kong/plugins/oidc/schema.lua index ffb55b37..177b46b4 100644 --- a/kong/plugins/oidc/schema.lua +++ b/kong/plugins/oidc/schema.lua @@ -1,6 +1,7 @@ return { no_consumer = true, fields = { + anonymous = { type = "string", uuid = true, legacy = true }, client_id = { type = "string", required = true }, client_secret = { type = "string", required = true }, discovery = { type = "string", required = true, default = "https://.well-known/openid-configuration" }, diff --git a/kong/plugins/oidc/utils.lua b/kong/plugins/oidc/utils.lua index 3686bbf6..fee13016 100644 --- a/kong/plugins/oidc/utils.lua +++ b/kong/plugins/oidc/utils.lua @@ -41,6 +41,7 @@ end function M.get_options(config, ngx) return { + anonymous = config.anonymous, client_id = config.client_id, client_secret = config.client_secret, discovery = config.discovery,