Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add redirect_after_logout_uri for ODIC that do not have an end_session_endpoint #10653

Merged
merged 13 commits into from
Dec 25, 2023
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
Loading