Skip to content

Commit

Permalink
fix(openid-connect): the default 'redirect_uri' (#2426) (#7690)
Browse files Browse the repository at this point in the history
Co-authored-by: Traky Deng <[email protected]>
Co-authored-by: lyy <[email protected]>
  • Loading branch information
3 people authored Dec 22, 2023
1 parent 06aa250 commit c7d406d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
19 changes: 17 additions & 2 deletions apisix/plugins/openid-connect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ local schema = {
},
redirect_uri = {
type = "string",
description = "use ngx.var.request_uri if not configured"
description = "auto append '.apisix/redirect' to ngx.var.uri if not configured"
},
post_logout_redirect_uri = {
type = "string",
Expand Down Expand Up @@ -441,7 +441,22 @@ function _M.rewrite(plugin_conf, ctx)
end

if not conf.redirect_uri then
conf.redirect_uri = ctx.var.request_uri
-- NOTE: 'lua-resty-openidc' requires that 'redirect_uri' be
-- different from 'uri'. So default to append the
-- '.apisix/redirect' suffix if not configured.
local suffix = "/.apisix/redirect"
local uri = ctx.var.uri
if core.string.has_suffix(uri, suffix) then
-- This is the redirection response from the OIDC provider.
conf.redirect_uri = uri
else
if string.sub(uri, -1, -1) == "/" then
conf.redirect_uri = string.sub(uri, 1, -2) .. suffix
else
conf.redirect_uri = uri .. suffix
end
end
core.log.debug("auto set redirect_uri: ", conf.redirect_uri)
end

if not conf.ssl_verify then
Expand Down
3 changes: 2 additions & 1 deletion docs/en/latest/plugins/openid-connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ description: OpenID Connect allows the client to obtain user information from th
| 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. |
| redirect_uri | string | False | "ngx.var.request_uri" | | URI to which the identity provider redirects back to. |
| 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. |
| introspection_endpoint | string | False | | | URL of the token verification endpoint of the identity server. |
Expand Down Expand Up @@ -229,3 +229,4 @@ In this example, the Plugin can enforce that the access token, the ID token, and

- `redirect_uri` needs to be captured by the route where the current APISIX is located. For example, the `uri` of the current route is `/api/v1/*`, `redirect_uri` can be filled in as `/api/v1/callback`;
- `scheme` and `host` of `redirect_uri` (`scheme:host`) are the values required to access APISIX from the perspective of the identity provider.
- `redirect_uri` should not be the same as the URI of the route. This is because when a user initiates a request to visit the protected resource, the request directly hits the redirection URI with no session cookie in the request, which leads to the `no session state found` error.
3 changes: 2 additions & 1 deletion docs/zh/latest/plugins/openid-connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ description: OpenID Connect(OIDC)是基于 OAuth 2.0 的身份认证协议
| bearer_only | boolean || false | | 当设置为 `true` 时,将仅检查请求头中的令牌(Token)。 |
| logout_path | string || "/logout" | | 登出路径。 |
| post_logout_redirect_uri | string || | | 调用登出接口后想要跳转的 URL。 |
| redirect_uri | string || "ngx.var.request_uri" | | 身份提供者重定向返回的 URI。 |
| 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 证书。 |
| introspection_endpoint | string || | | 用于内省访问令牌的身份提供者的令牌内省端点的 URL。如果未设置,则使用发现文档中提供的内省端点[作为后备](https://github.com/zmartzone/lua-resty-openidc/commit/cdaf824996d2b499de4c72852c91733872137c9c)|
Expand Down Expand Up @@ -226,3 +226,4 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 \

- `redirect_uri` 需要能被当前 APISIX 所在路由捕获,比如当前路由的 `uri``/api/v1/*`, `redirect_uri` 可以填写为 `/api/v1/callback`
- `redirect_uri``scheme:host`)的 `scheme``host` 是身份认证服务视角下访问 APISIX 所需的值。
- `redirect_uri` 不应与路由的 URI 相同。这是因为当用户发起访问受保护资源的请求时,请求会直接指向重定向 URI,而请求中没有会话 cookie,从而导致 `no session state found` 错误。
67 changes: 67 additions & 0 deletions t/plugin/openid-connect2.t
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,70 @@ passed
--- timeout: 10s
--- response_body
true
=== TEST 9: Set up route with plugin matching URI `/hello` with redirect_uri use default value.
--- 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": "http://127.0.0.1:1980/.well-known/openid-configuration",
"ssl_verify": false,
"timeout": 10,
"scope": "apisix",
"unauth_action": "auth",
"use_pkce": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 10: The value of redirect_uri should be appended to `.apisix/redirect` in the original request.
--- 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 .. "/hello"
local redirect_uri = uri .. "/.apisix/redirect"
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://samples.auth0.com/authorize') ~= -1 and
string.find(location, 'scope=apisix') ~= -1 and
string.find(location, 'client_id=kbyuFDidLLm280LIwVFiazOqjO3ty8KH') ~= -1 and
string.find(location, 'response_type=code') ~= -1 and
string.find(location, 'redirect_uri=' .. redirect_uri) ~= -1 then
ngx.say(true)
end
}
}
--- timeout: 10s
--- response_body
true
--- error_code: 302

0 comments on commit c7d406d

Please sign in to comment.