Skip to content

Commit

Permalink
added anonymous support compatible with kong 1.0.X
Browse files Browse the repository at this point in the history
  • Loading branch information
emoj authored and emoj committed Apr 9, 2019
1 parent f0c573c commit 0558791
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 47 deletions.
89 changes: 63 additions & 26 deletions kong/plugins/oidc/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ 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"

local kong = kong

OidcHandler.PRIORITY = 1000

local function internal_server_error(err)
kong.log.err(err)
return kong.response.exit(500, { message = "An unexpected error occurred" })
end

function OidcHandler:new()
OidcHandler.super.new(self, "oidc")
Expand All @@ -18,7 +22,7 @@ end
function OidcHandler:access(config)
OidcHandler.super.access(self)

if ngx.ctx.authenticated_credential and config.anonymous ~= "" then
if config.anonymous and kong.client.get_credential() 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
Expand Down Expand Up @@ -69,19 +73,20 @@ function make_oidc(oidcConfig)
ngx.log(ngx.DEBUG, "Entering recovery page: " .. oidcConfig.recovery_page_path)
ngx.redirect(oidcConfig.recovery_page_path)
end
if oidcConfig.anonymous ~= "" then
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)
local consumer_cache_key = kong.db.consumers:cache_key(oidcConfig.anonymous)
local consumer, err = kong.cache:get(consumer_cache_key, nil,
load_consumer_into_memory,
oidcConfig.anonymous, true)
if err then
return responses.send_HTTP_INTERNAL_SERVER_ERROR(err)
return internal_server_error(err)
end

set_consumer(consumer, nil, nil)

else
utils.exit(500, err, ngx.HTTP_INTERNAL_SERVER_ERROR)
return kong.response.exit(err.status, err.message, err.headers)
end
end
return res
Expand All @@ -93,19 +98,20 @@ function introspect(oidcConfig)
if err then
if oidcConfig.bearer_only == "yes" then
ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. oidcConfig.realm .. '",error="' .. err .. '"'
if oidcConfig.anonymous ~= "" then
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)
local consumer_cache_key = kong.db.consumers:cache_key(oidcConfig.anonymous)
local consumer, err = kong.cache:get(consumer_cache_key, nil,
load_consumer_into_memory,
oidcConfig.anonymous, true)
if err then
return responses.send_HTTP_INTERNAL_SERVER_ERROR(err)
return internal_server_error(err)
end

set_consumer(consumer, nil, nil)

else
utils.exit(ngx.HTTP_UNAUTHORIZED, err, ngx.HTTP_UNAUTHORIZED)
return kong.response.exit(err.status, err.message, err.headers)
end

end
Expand All @@ -120,17 +126,48 @@ 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
local set_header = kong.service.request.set_header
local clear_header = kong.service.request.clear_header

if consumer and consumer.id then
set_header(constants.HEADERS.CONSUMER_ID, consumer.id)
else
clear_header(constants.HEADERS.CONSUMER_ID)
end

if consumer and consumer.custom_id then
set_header(constants.HEADERS.CONSUMER_CUSTOM_ID, consumer.custom_id)
else
clear_header(constants.HEADERS.CONSUMER_CUSTOM_ID)
end

if consumer and consumer.username then
set_header(constants.HEADERS.CONSUMER_USERNAME, consumer.username)
else
clear_header(constants.HEADERS.CONSUMER_USERNAME)
end

kong.client.authenticate(consumer, credential)

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
if token.scope then
set_header("x-authenticated-scope", token.scope)
else
clear_header("x-authenticated-scope")
end

if token.authenticated_userid then
set_header("x-authenticated-userid", token.authenticated_userid)
else
clear_header("x-authenticated-userid")
end

clear_header(constants.HEADERS.ANONYMOUS) -- in case of auth plugins concatenation

else
ngx_set_header(constants.HEADERS.ANONYMOUS, true)
set_header(constants.HEADERS.ANONYMOUS, true)
clear_header("x-authenticated-scope")
clear_header("x-authenticated-userid")
end

end
Expand Down
59 changes: 38 additions & 21 deletions kong/plugins/oidc/schema.lua
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
local typedefs = require "kong.db.schema.typedefs"

local function validate_flows(config)

return true

end

return {
no_consumer = true,
name = "oidc",
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" },
introspection_endpoint = { type = "string", required = false },
timeout = { type = "number", required = false },
introspection_endpoint_auth_method = { type = "string", required = false },
bearer_only = { type = "string", required = true, default = "no" },
realm = { type = "string", required = true, default = "kong" },
redirect_uri_path = { type = "string" },
scope = { type = "string", required = true, default = "openid" },
response_type = { type = "string", required = true, default = "code" },
ssl_verify = { type = "string", required = true, default = "no" },
token_endpoint_auth_method = { type = "string", required = true, default = "client_secret_post" },
session_secret = { type = "string", required = false },
recovery_page_path = { type = "string" },
logout_path = { type = "string", required = false, default = '/logout' },
redirect_after_logout_uri = { type = "string", required = false, default = '/' },
filters = { type = "string" }
}
{ consumer = typedefs.no_consumer },
{ run_on = typedefs.run_on_first },
{ config = {
type = "record",
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" }},
{introspection_endpoint = { type = "string", required = false }},
{timeout = { type = "number", required = false }},
{introspection_endpoint_auth_method = { type = "string", required = false }},
{bearer_only = { type = "string", required = true, default = "no" }},
{realm = { type = "string", required = true, default = "kong" }},
{redirect_uri_path = { type = "string" }},
{scope = { type = "string", required = true, default = "openid" }},
{response_type = { type = "string", required = true, default = "code" }},
{ssl_verify = { type = "string", required = true, default = "no" }},
{token_endpoint_auth_method = { type = "string", required = true, default = "client_secret_post" }},
{session_secret = { type = "string", required = false }},
{recovery_page_path = { type = "string" }},
{logout_path = { type = "string", required = false, default = '/logout' }},
{redirect_after_logout_uri = { type = "string", required = false, default = '/' }},
{filters = { type = "string" }}
},
custom_validator = validate_flows,
},
},
},
}

0 comments on commit 0558791

Please sign in to comment.