Skip to content

Commit

Permalink
fix(openid-connect): add redirect_after_logout_uri for ODIC that do n…
Browse files Browse the repository at this point in the history
…ot have an end_session_endpoint (#10653)
  • Loading branch information
luoluoyuyu authored Dec 25, 2023
1 parent 3d5c5fa commit 129844c
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 2 deletions.
15 changes: 15 additions & 0 deletions apisix/plugins/openid-connect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ function _M.rewrite(plugin_conf, ctx)
conf.timeout = conf.timeout * 1000
end

local path = ctx.var.request_uri

if not conf.redirect_uri then
-- NOTE: 'lua-resty-openidc' requires that 'redirect_uri' be
-- different from 'uri'. So default to append the
Expand All @@ -464,6 +466,19 @@ function _M.rewrite(plugin_conf, ctx)
conf.ssl_verify = "no"
end

if path == (conf.logout_path or "/logout") then
local discovery, discovery_err = openidc.get_discovery_doc(conf)
if discovery_err then
core.log.error("OIDC access discovery url failed : ", discovery_err)
return 503
end
if conf.post_logout_redirect_uri and not discovery.end_session_endpoint then
-- If the end_session_endpoint field does not exist in the OpenID Provider Discovery
-- Metadata, the redirect_after_logout_uri field is used for redirection.
conf.redirect_after_logout_uri = conf.post_logout_redirect_uri
end
end

local response, err, session, _

if conf.bearer_only or conf.introspection_endpoint or conf.public_key then
Expand Down
2 changes: 1 addition & 1 deletion docs/en/latest/plugins/openid-connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ description: OpenID Connect allows the client to obtain user information from th
| realm | string | False | "apisix" | | Realm used for authentication. |
| bearer_only | boolean | False | false | | When set to `true`, APISIX will only check if the authorization header in the request matches a bearer token. |
| logout_path | string | False | "/logout" | | Path for logging out. |
| post_logout_redirect_uri | string | False | | | URL to redirect to after logging out. |
| post_logout_redirect_uri | string | False | | | URL to redirect to after logging out. If the OIDC discovery endpoint does not provide an [`end_session_endpoint`](https://openid.net/specs/openid-connect-rpinitiated-1_0.html), the plugin internally redirects using the [`redirect_after_logout_uri`](https://github.com/zmartzone/lua-resty-openidc). Otherwise, it redirects using the [`post_logout_redirect_uri`](https://openid.net/specs/openid-connect-rpinitiated-1_0.html). |
| redirect_uri | string | False | | | URI to which the identity provider redirects back to. If not configured, APISIX will append the `.apisix/redirect` suffix to determine the default `redirect_uri`. Note that the provider should be properly configured to allow such `redirect_uri` values. |
| timeout | integer | False | 3 | [1,...] | Request timeout time in seconds. |
| ssl_verify | boolean | False | false | | When set to true, verifies the identity provider's SSL certificates. |
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/latest/plugins/openid-connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ description: OpenID Connect(OIDC)是基于 OAuth 2.0 的身份认证协议
| realm | string || "apisix" | | bearer token 无效时 [`WWW-Authenticate` 响应头](https://www.rfc-editor.org/rfc/rfc6750#section-3)中会伴随着的 `realm` 讯息。 |
| bearer_only | boolean || false | | 当设置为 `true` 时,将仅检查请求头中的令牌(Token)。 |
| logout_path | string || "/logout" | | 登出路径。 |
| post_logout_redirect_uri | string || | | 调用登出接口后想要跳转的 URL。 |
| post_logout_redirect_uri | string || | | 调用登出接口后想要跳转的 URL。如果 OIDC 的服务发现端点没有提供 [`end_session_endpoint`](https://openid.net/specs/openid-connect-rpinitiated-1_0.html) ,插件内部会使用 [`redirect_after_logout_uri`](https://github.com/zmartzone/lua-resty-openidc) 进行重定向,否则使用 [`post_logout_redirect_uri`](https://openid.net/specs/openid-connect-rpinitiated-1_0.html) 进行重定向。 |
| redirect_uri | string || | | 身份提供者重定向返回的 URI。如果缺失,则 APISIX 将在当前 URI 之后追加 `.apisix/redirect` 作为默认的 `redirect_uri`。注意,OP 也需要适当配置以允许这种形式的 `redirect_uri`|
| timeout | integer || 3 | [1,...] | 请求超时时间,单位为秒 |
| ssl_verify | boolean || false | [true, false] | 当设置为 `true` 时,验证身份提供者的 SSL 证书。 |
Expand Down
122 changes: 122 additions & 0 deletions t/plugin/openid-connect.t
Original file line number Diff line number Diff line change
Expand Up @@ -1303,3 +1303,125 @@ passed
}
--- response_body_like
x-userinfo: ey.*
=== TEST 34: Set up new route with plugin matching URI `/*`
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{ "plugins": {
"openid-connect": {
"client_id": "kbyuFDidLLm280LIwVFiazOqjO3ty8KH",
"client_secret": "60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa",
"discovery": "https://samples.auth0.com/.well-known/openid-configuration",
"redirect_uri": "https://iresty.com",
"post_logout_redirect_uri": "https://iresty.com",
"scope": "openid profile"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 35: Check whether auth0 can redirect normally using post_logout_redirect_uri configuration
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/logout"
local res, err = httpc:request_uri(uri, {method = "GET"})
ngx.status = res.status
local location = res.headers['Location']
if location and string.find(location, 'https://iresty.com') ~= -1 and
string.find(location, 'post_logout_redirect_uri=https://iresty.com') ~= -1 then
ngx.say(true)
end
}
}
--- timeout: 10s
--- response_body
true
--- error_code: 302
=== TEST 36: Set up new route with plugin matching URI `/*`
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{ "plugins": {
"openid-connect": {
"client_id": "942299072001-vhduu1uljmdhhbbp7g22m3qsmo246a75.apps.googleusercontent.com",
"client_secret": "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",
"discovery": "https://accounts.google.com/.well-known/openid-configuration",
"redirect_uri": "https://iresty.com",
"post_logout_redirect_uri": "https://iresty.com",
"scope": "openid profile"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 37: Check whether google can redirect normally using post_logout_redirect_uri configuration
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/logout"
local res, err = httpc:request_uri(uri, {method = "GET"})
ngx.status = res.status
local location = res.headers['Location']
if location and string.find(location, 'https://iresty.com') ~= -1 and
string.find(location, 'post_logout_redirect_uri=https://iresty.com') ~= -1 then
ngx.say(true)
end
}
}
--- timeout: 10s
--- response_body
true
--- error_code: 302

0 comments on commit 129844c

Please sign in to comment.