Keycloak:注销后,访问令牌仍然可以使用

问题描述 投票:0回答:1

我有一个 nginx/openresty 客户端到 keycloak 服务器,使用 openid 进行授权。 我正在使用 lua-resty-openidc 来允许访问代理后面的服务。

用户可以访问他的个人资料:

https://<my-server>/auth/realms/<real-name>/account
并通过注销
https://<my-server>/auth/realms/<real-name>/protocol/openid-connect/logout

问题是,即使注销后,用户仍然可以访问服务器后面的服务,基本上看起来他从 keycloak 获得的令牌仍然有效或者什么的....这也是其他人观察到的行为用户,请参阅例如有关如何从 keycloak 注销的问题来自 ch271828n 的评论

如何确保用户注销后,在重新登录之前将无法再访问?

keycloak openid openresty
1个回答
4
投票

我必须检查lua源代码,但我想我已经弄清楚了注销行为:Lua-resty-openidc建立会话,并且当检测到特定的url访问时它们被终止(它由

opts.logout_path
控制)我们需要将其设置为服务路径中的地址,例如.../service/logout)

本质上,需要点击两个url,一个用于keycloak注销,一个用于openresty会话注销。在我们访问位于

https://<keycloak-server>/auth/realms/<my-realm>/protocol/openid-connect/logout
 的 opts.logout_path 后,访问 keycloak 注销 url 
https://<our-nginx-server>/service/logout

是由 lua 完成的

因此,正确设置所有内容后我们要做的就是注销点击

https://<our-nginx-server>/service/logout
。这将破坏会话并使我们退出。

我认为我们需要将

opts.revoke_tokens_on_logout
设置为
true
,另请注意,从我的实验来看,由于某种原因,设置
redirect_after_logout_uri
可能会导致用户由于重定向而无法注销。

为了重定向到例如注销后的 foo.bar 我们可以执行

?redirect_uri=https://foo.bar/
部分。我们还可以重定向回我们的服务页面,在这种情况下,它将要求重新进行身份验证...

这是我们需要 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,
            redirect_after_logout_uri = "https://<keycloak-server>/auth/realms/<my-realm>/protocol/openid-connect/logout?redirect_uri=https://foo.bar/",
            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";
}
© www.soinside.com 2019 - 2024. All rights reserved.