Keycloak:注销后,访问令牌仍然可以使用
Keycloack: After logout, the access token can still be used
我有一个 nginx/openresty 客户端到 keycloack 服务器,使用 openid 进行授权。
我正在使用 lua-resty-openidc 来允许访问代理后面的服务。
用户可以访问他的个人资料
https://<my-server>/auth/realms/<real-name>/account
并通过注销
https://<my-server>/auth/realms/<real-name>/protocol/openid-connect/logout
问题是,即使注销后,用户仍然可以访问服务器后面的服务,基本上他从keycloak获得的令牌似乎仍然有效之类的....这也是一种行为被其他用户观察到,例如 this question on how to logout from keycloak 来自 ch271828n
的评论
我如何确保用户注销后在重新登录之前无法访问?
我不得不检查 lua source code,但我想我已经弄清楚了注销行为:Lua-resty-openidc 建立会话,并且当特定 url 检测到访问(它由 opts.logout_path
控制,我们需要将其设置为服务路径中的地址,例如 .../service/logout)
本质上有两个url需要命中,一个是keycloack logout,一个是openresty session logout。在 https://<our-nginx-server>/service/logout
访问 opts.logout_path 之后,lua 访问 keycloack 注销 url https://<keycloak-server>/auth/realms/<my-realm>/protocol/openid-connect/logout
所以在正确设置所有内容后,我们需要做的注销就是点击https://<our-nginx-server>/service/logout
。这将破坏会话并注销我们。
我认为我们需要将 opts.revoke_tokens_on_logout
设置为 true
,另外请注意,根据我的实验,由于某些原因,设置 redirect_after_logout_uri
可能会导致用户无法退出由于重定向。
这里是我们 nginx.conf 完成这项工作所需的示例....
location /myservice/ {
access_by_lua_block {
local opts = {
redirect_uri_path = "/myservice/auth",
discovery = "https://<keycloak-server>/auth/realms/<my-realm>/.well-known/openid-configuration",
client_id = "<my-client-id>",
client_secret = "<the-clients-secret>",
logout_path = "/service/logout",
revoke_tokens_on_logout = true,
session_contents = {id_token=true} -- this is essential for safari!
}
-- call introspect for OAuth 2.0 Bearer Access Token validation
local res, err = require("resty.openidc").authenticate(opts)
if err then
ngx.status = 403
ngx.say(err)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
# I disbled caching so the browser won't cache the site.
expires 0;
add_header Cache-Control private;
proxy_pass http://my-service-server.cloud:port/some/path/;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
我有一个 nginx/openresty 客户端到 keycloack 服务器,使用 openid 进行授权。 我正在使用 lua-resty-openidc 来允许访问代理后面的服务。
用户可以访问他的个人资料
https://<my-server>/auth/realms/<real-name>/account
并通过注销
https://<my-server>/auth/realms/<real-name>/protocol/openid-connect/logout
问题是,即使注销后,用户仍然可以访问服务器后面的服务,基本上他从keycloak获得的令牌似乎仍然有效之类的....这也是一种行为被其他用户观察到,例如 this question on how to logout from keycloak 来自 ch271828n
的评论我如何确保用户注销后在重新登录之前无法访问?
我不得不检查 lua source code,但我想我已经弄清楚了注销行为:Lua-resty-openidc 建立会话,并且当特定 url 检测到访问(它由 opts.logout_path
控制,我们需要将其设置为服务路径中的地址,例如 .../service/logout)
本质上有两个url需要命中,一个是keycloack logout,一个是openresty session logout。在 https://<our-nginx-server>/service/logout
https://<keycloak-server>/auth/realms/<my-realm>/protocol/openid-connect/logout
所以在正确设置所有内容后,我们需要做的注销就是点击https://<our-nginx-server>/service/logout
。这将破坏会话并注销我们。
我认为我们需要将 opts.revoke_tokens_on_logout
设置为 true
,另外请注意,根据我的实验,由于某些原因,设置 redirect_after_logout_uri
可能会导致用户无法退出由于重定向。
这里是我们 nginx.conf 完成这项工作所需的示例....
location /myservice/ {
access_by_lua_block {
local opts = {
redirect_uri_path = "/myservice/auth",
discovery = "https://<keycloak-server>/auth/realms/<my-realm>/.well-known/openid-configuration",
client_id = "<my-client-id>",
client_secret = "<the-clients-secret>",
logout_path = "/service/logout",
revoke_tokens_on_logout = true,
session_contents = {id_token=true} -- this is essential for safari!
}
-- call introspect for OAuth 2.0 Bearer Access Token validation
local res, err = require("resty.openidc").authenticate(opts)
if err then
ngx.status = 403
ngx.say(err)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
# I disbled caching so the browser won't cache the site.
expires 0;
add_header Cache-Control private;
proxy_pass http://my-service-server.cloud:port/some/path/;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}