Skip to content

Commit

Permalink
Compile latest update of the plugin that could be found on internet &…
Browse files Browse the repository at this point in the history
… fix request to the redirect_uri path but there's no session state found
  • Loading branch information
ricristian committed Nov 3, 2024
1 parent 2510459 commit 17289c2
Show file tree
Hide file tree
Showing 29 changed files with 1,238 additions and 288 deletions.
11 changes: 6 additions & 5 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ BUILD_IMG_NAME=nokia/kong-oidc
INTEGRATION_PATH=test/docker/integration
UNIT_PATH=test/docker/unit

KONG_BASE_TAG=:1.0-centos
KONG_BASE_TAG=:2.8.0-ubuntu
KONG_TAG=
KONG_DB_TAG=:10.1
KONG_DB_TAG=:14
KONG_DB_PORT=5432
KONG_DB_USER=kong
KONG_DB_PW=kong
KONG_DB_NAME=kong
KONG_SESSION_STORE_PORT=6379
KONG_HTTP_PROXY_PORT=8000
KONG_HTTP_ADMIN_PORT=8001

KEYCLOAK_TAG=:4.8.3.Final
KEYCLOAK_PORT=8080
KEYCLOAK_TAG=:16.1.1
KEYCLOAK_PORT=8081
KEYCLOAK_USER=admin
KEYCLOAK_PW=password
KEYCLOAK_PW=password
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,14 @@
\#*\#
.\#*
lua_install
luacov.stats.out
luacov.stats.out
venv/
bin/venv/
**/__pycache__/
# Visual Studio Code
.vscode/

# IntelliJ IDEA
*.iml
.idea
.dccache
6 changes: 1 addition & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ language: python
sudo: true

env:
- LUA_VERSION="5.1" KONG_VERSION="0.13.0-0" LUA_RESTY_OPENIDC_VERSION="1.6.1-1"
- LUA_VERSION="5.1" KONG_VERSION="0.12.3-0" LUA_RESTY_OPENIDC_VERSION="1.6.1-1"
- LUA_VERSION="5.1" KONG_VERSION="0.11.2-0" LUA_RESTY_OPENIDC_VERSION="1.6.1-1"
- LUA_VERSION="5.1" KONG_VERSION="1.0.2-0" LUA_RESTY_OPENIDC_VERSION="1.6.1-1"
- LUA_VERSION="5.1" KONG_VERSION="1.5.0-0" LUA_RESTY_OPENIDC_VERSION="1.7.2-1"

script:
- sudo -E bash ci/root.sh
Expand All @@ -18,4 +15,3 @@ script:
after_success:
- luarocks install luacov-coveralls
- luacov-coveralls

21 changes: 21 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
List of authors based on the git log:

Adam Płaczek <[email protected]>
Damian Czaja <[email protected]>
Geoff Kassel <[email protected]>
Gergely Csatari <[email protected]>
Hannu Laurila <[email protected]>
Joshua Erney <[email protected]>
Lars Wilhelmsen <[email protected]>
Luka Lodrant <[email protected]>
Micah Silverman <[email protected]>
Michal Kulik <[email protected]>
Nazarii Makarenko <[email protected]>
Pavel Mikhalchuk <[email protected]>
pekka.hirvonen <[email protected]>
The Gitter Badger <[email protected]>
Tom Milligan <[email protected]>
Trojan295 <[email protected]>
Tuomo Syrjanen <[email protected]>
Yoriyasu Yano <[email protected]>
Yuan Cheung <[email protected]>
148 changes: 112 additions & 36 deletions README.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion bin/build-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
# Tear down environment if it is running
docker-compose -f ${INTEGRATION_PATH}/docker-compose.yml down
docker build --build-arg KONG_BASE_TAG=${KONG_BASE_TAG} -t nokia/kong-oidc -f ${INTEGRATION_PATH}/Dockerfile .
docker-compose -f ${INTEGRATION_PATH}/docker-compose.yml up -d kong-db
docker-compose -f ${INTEGRATION_PATH}/docker-compose.yml up -d kong-db kong-session-store
)

_wait_for_listener localhost:${KONG_DB_PORT}
_wait_for_listener localhost:${KONG_SESSION_STORE_PORT}

(set -x
docker-compose -f ${INTEGRATION_PATH}/docker-compose.yml run --rm kong kong migrations bootstrap
Expand Down
9 changes: 9 additions & 0 deletions bin/my-ip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
ADAPTER=""
if [ -z "$*" ]; then
ADAPTER="wifi0"
else
ADAPTER=$1
fi

ip addr show $ADAPTER | grep "inet\b" | awk '{print $2}' | cut -d/ -f1
3 changes: 1 addition & 2 deletions ci/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -e

export LUA_VERSION=${LUA_VERSION:-5.1}
export KONG_VERSION=${KONG_VERSION:-0.13.1-0}
export LUA_RESTY_OPENIDC_VERSION=${LUA_RESTY_OPENIDC_VERSION:-1.6.1-1}
export LUA_RESTY_OPENIDC_VERSION=${LUA_RESTY_OPENIDC_VERSION:-1.7.1-1}

pip install hererocks
hererocks lua_install -r^ --lua=${LUA_VERSION}
Expand All @@ -14,4 +14,3 @@ luarocks install lua-resty-openidc ${LUA_RESTY_OPENIDC_VERSION}
luarocks install lua-cjson
luarocks install luaunit
luarocks install luacov

14 changes: 7 additions & 7 deletions kong-oidc-1.1.0-0.rockspec → kong-plugin-oidc-1.4.0-1.rockspec
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package = "kong-oidc"
version = "1.1.0-0"
package = "kong-oidc-v3"
version = "1.4.0-1"
source = {
url = "git://github.com/nokia/kong-oidc",
tag = "v1.1.0",
dir = "kong-oidc"
url = "git://github.com/ricristian/kong-oidc-v3",
tag = "master",
dir = "kong-oidc-v3"
}
description = {
summary = "A Kong plugin for implementing the OpenID Connect Relying Party (RP) functionality",
Expand All @@ -18,11 +18,11 @@ description = {
It can be used as a reverse proxy terminating OAuth/OpenID Connect in front of an origin server so that the origin server/services can be protected with the relevant standards without implementing those on the server itself.
]],
homepage = "https://github.com/nokia/kong-oidc",
homepage = "git://github.com/ricristian/kong-oidc-v3",
license = "Apache 2.0"
}
dependencies = {
"lua-resty-openidc ~> 1.6.1-1"
"lua-resty-openidc ~> 1.8.0-1"
}
build = {
type = "builtin",
Expand Down
154 changes: 131 additions & 23 deletions kong/plugins/oidc/handler.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
local BasePlugin = require "kong.plugins.base_plugin"
local OidcHandler = BasePlugin:extend()
local OidcHandler = {
VERSION = "1.3.0",
PRIORITY = 1000,
}
local utils = require("kong.plugins.oidc.utils")
local filter = require("kong.plugins.oidc.filter")
local session = require("kong.plugins.oidc.session")

OidcHandler.PRIORITY = 1000


function OidcHandler:new()
OidcHandler.super.new(self, "oidc")
end

function OidcHandler:access(config)
OidcHandler.super.access(self)
local oidcConfig = utils.get_options(config, ngx)

-- partial support for plugin chaining: allow skipping requests, where higher priority
-- plugin has already set the credentials. The 'config.anomyous' approach to define
-- "and/or" relationship between auth plugins is not utilized
if oidcConfig.skip_already_auth_requests and kong.client.get_credential() then
ngx.log(ngx.DEBUG, "OidcHandler ignoring already auth request: " .. ngx.var.request_uri)
return
end

if filter.shouldProcessRequest(oidcConfig) then
session.configure(config)
handle(oidcConfig)
Expand All @@ -27,57 +30,162 @@ end

function handle(oidcConfig)
local response

if oidcConfig.bearer_jwt_auth_enable then
response = verify_bearer_jwt(oidcConfig)
if response then
utils.setCredentials(response)
utils.injectGroups(response, oidcConfig.groups_claim)
utils.injectHeaders(oidcConfig.header_names, oidcConfig.header_claims, { response })
if not oidcConfig.disable_userinfo_header then
utils.injectUser(response, oidcConfig.userinfo_header_name)
end
return
end
end

if oidcConfig.introspection_endpoint then
response = introspect(oidcConfig)
if response then
utils.injectUser(response)
utils.setCredentials(response)
utils.injectGroups(response, oidcConfig.groups_claim)
utils.injectHeaders(oidcConfig.header_names, oidcConfig.header_claims, { response })
if not oidcConfig.disable_userinfo_header then
utils.injectUser(response, oidcConfig.userinfo_header_name)
end
end
end

if response == nil then
response = make_oidc(oidcConfig)
if response then
if (response.user) then
utils.injectUser(response.user)
if response.user or response.id_token then
-- is there any scenario where lua-resty-openidc would not provide id_token?
utils.setCredentials(response.user or response.id_token)
end
if (response.access_token) then
utils.injectAccessToken(response.access_token)
if response.user and response.user[oidcConfig.groups_claim] ~= nil then
utils.injectGroups(response.user, oidcConfig.groups_claim)
elseif response.id_token then
utils.injectGroups(response.id_token, oidcConfig.groups_claim)
end
if (response.id_token) then
utils.injectIDToken(response.id_token)
utils.injectHeaders(oidcConfig.header_names, oidcConfig.header_claims, { response.user, response.id_token })
if (not oidcConfig.disable_userinfo_header
and response.user) then
utils.injectUser(response.user, oidcConfig.userinfo_header_name)
end
if (not oidcConfig.disable_access_token_header
and response.access_token) then
utils.injectAccessToken(response.access_token, oidcConfig.access_token_header_name, oidcConfig.access_token_as_bearer)
end
if (not oidcConfig.disable_id_token_header
and response.id_token) then
utils.injectIDToken(response.id_token, oidcConfig.id_token_header_name)
end
end
end
end

function make_oidc(oidcConfig)
ngx.log(ngx.DEBUG, "OidcHandler calling authenticate, requested path: " .. ngx.var.request_uri)
local res, err = require("resty.openidc").authenticate(oidcConfig)
local unauth_action = oidcConfig.unauth_action
if unauth_action ~= "auth" then
-- constant for resty.oidc library
unauth_action = "deny"
end
local res, err = require("resty.openidc").authenticate(oidcConfig, ngx.var.request_uri, unauth_action)

if err then
if oidcConfig.recovery_page_path then
ngx.log(ngx.DEBUG, "Entering recovery page: " .. oidcConfig.recovery_page_path)
ngx.redirect(oidcConfig.recovery_page_path)
if err == 'unauthorized request' then
return kong.response.error(ngx.HTTP_UNAUTHORIZED)
else
if oidcConfig.recovery_page_path then
ngx.log(ngx.DEBUG, "Redirecting to recovery page: " .. oidcConfig.recovery_page_path)
ngx.redirect(oidcConfig.recovery_page_path)
end
return kong.response.error(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
utils.exit(500, err, ngx.HTTP_INTERNAL_SERVER_ERROR)
end
return res
end

function introspect(oidcConfig)
if utils.has_bearer_access_token() or oidcConfig.bearer_only == "yes" then
local res, err = require("resty.openidc").introspect(oidcConfig)
local res, err
if oidcConfig.use_jwks == "yes" then
res, err = require("resty.openidc").bearer_jwt_verify(oidcConfig)
else
res, err = require("resty.openidc").introspect(oidcConfig)
end
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)
return kong.response.error(ngx.HTTP_UNAUTHORIZED)
end
return nil
end
if oidcConfig.validate_scope == "yes" then
local validScope = false
if res.scope then
for scope in res.scope:gmatch("([^ ]+)") do
if scope == oidcConfig.scope then
validScope = true
break
end
end
end
if not validScope then
kong.log.err("Scope validation failed")
return kong.response.error(ngx.HTTP_FORBIDDEN)
end
end
ngx.log(ngx.DEBUG, "OidcHandler introspect succeeded, requested path: " .. ngx.var.request_uri)
return res
end
return nil
end

function verify_bearer_jwt(oidcConfig)
if not utils.has_bearer_access_token() then
return nil
end
-- setup controlled configuration for bearer_jwt_verify
local opts = {
accept_none_alg = false,
accept_unsupported_alg = false,
token_signing_alg_values_expected = oidcConfig.bearer_jwt_auth_signing_algs,
discovery = oidcConfig.discovery,
timeout = oidcConfig.timeout,
ssl_verify = oidcConfig.ssl_verify
}

local discovery_doc, err = require("resty.openidc").get_discovery_doc(opts)
if err then
kong.log.err('Discovery document retrieval for Bearer JWT verify failed')
return nil
end

local allowed_auds = oidcConfig.bearer_jwt_auth_allowed_auds or oidcConfig.client_id

local jwt_validators = require "resty.jwt-validators"
jwt_validators.set_system_leeway(120)
local claim_spec = {
-- mandatory for id token: iss, sub, aud, exp, iat
iss = jwt_validators.equals(discovery_doc.issuer),
sub = jwt_validators.required(),
aud = function(val) return utils.has_common_item(val, allowed_auds) end,
exp = jwt_validators.is_not_expired(),
iat = jwt_validators.required(),
-- optional validations
nbf = jwt_validators.opt_is_not_before(),
}

local json, err, token = require("resty.openidc").bearer_jwt_verify(opts, claim_spec)
if err then
kong.log.err('Bearer JWT verify failed: ' .. err)
return nil
end

return json
end

return OidcHandler
Loading

0 comments on commit 17289c2

Please sign in to comment.