Keycloak 注销不会结束会话

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

我在 Java 应用程序中使用 Keycloak 3.4,使用 Spring Framework 和 Jetty 8.1 以及 Keycloak Jetty-81-Adapter 3.4。

根据 Keycloak 文档,我应该能够在 Java EE 应用程序中使用 HttpServletRequest 从 Keycloak 注销。然而,这在我的情况下不起作用,即使 Jetty 支持 HttpServletRequests。

您可以通过多种方式注销 Web 应用程序。对于 Java EE servlet 容器,您可以调用 HttpServletRequest.logout()..

如果我尝试以这种方式注销,我会被重定向到 keycloak(登录屏幕,可以选择从多个领域登录中进行选择)。然而,当我选择我的首选领域时,我会立即再次登录到 Web 应用程序,而无需提供任何凭据。

我尝试了另一种方法,重定向到 Keycloak:

对于其他浏览器应用程序,您可以将浏览器重定向到
http://auth-server/auth/realms/{领域名称}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri

但它会在 Keycloak 日志中抛出连接拒绝错误,因为 Keycloak 尝试以直接方式调用我的 web 应用程序。它对保持活动状态的 Keycloak 会话没有影响。我强烈希望不需要从 Keycloak 直接调用 Web 应用程序的服务器端调用。

有什么建议为什么

HttpServletRequest.logout()
不会破坏我的情况下的 keycloak 会话吗? HttpServletRequest 的 Jetty 实现与 Java EE 实现有很大不同,以至于根本无法工作吗?

java logout embedded-jetty keycloak
5个回答
10
投票

我在使用远程(OIDC)身份提供商时也有过类似的经历。我发现

HttpServletRequest.logout
实际上破坏了
Keycloak
中的会话,但没有传播到我的远程身份提供商的注销 URL。当转到远程登录站点时,它立即将我重定向回来,看到我有一个活动会话。这看起来很像 keycloak 会话实际上并没有失效,但我检查了一下,确实如此。使用浏览器重定向到该 url 会在两个地方都注销。可能是
Keycloak
中的错误。

您是否也面临同样的问题?要进行验证,请尝试注销,然后在 keycloak 中选择您的客户端并列出会话,以查看它是否仍然存在于 Keycloak 中。


5
投票

如果从不受保护的页面(不检查有效令牌的页面)执行方法(注销),刷新令牌可能不可用,在这种情况下,适配器会跳过调用。因此,建议使用受保护的页面来执行 HttpServletRequest.logout(),以便始终考虑当前令牌,并在需要时执行与 Keycloak 服务器的交互。 https://www.keycloak.org/docs/latest/securing_apps/index.html#logout

这在受保护的页面中对我有用,但在不受保护的页面中不起作用

public ExternalContext currentExternalContext() {
        if (FacesContext.getCurrentInstance() == null) {
            throw new RuntimeException("message here ");
        } else {
            return FacesContext.getCurrentInstance().getExternalContext();
         }
    }

public void logout() throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) currentExternalContext().getRequest();
    ExternalContext externalContext = currentExternalContext();
    request.logout();
    externalContext.redirect(externalContext.getRequestContextPath());
}

1
投票

您需要将包含“request.logout()”操作的 Servlet 或 Rest 作为受保护资源,以便令牌可用:

查看以下文档: ”

服务器传递刷新令牌。如果该方法是从 不受保护的页面(不检查有效令牌的页面) 刷新令牌可能不可用,在这种情况下,适配器会跳过 的电话。为此,使用受保护的页面来执行 建议使用 HttpServletRequest.logout() 以便当前令牌 始终考虑到与 {project_name} 的互动 如果需要,将执行服务器。


1
投票

您可以将“用户会话计数限制器”扩展添加到浏览器流程中: User Session Count Limiter screenshot

并将其配置为一个会话并终止最旧的会话: configure it to one session screenshot

您可以查看 Keycloak 文档


0
投票

如果它对某人有帮助,这对我来说非常有用 https://www.reddit.com/r/nextjs/comments/redv1r/comment/hvho7va/?context=3&rdt=62018

© www.soinside.com 2019 - 2024. All rights reserved.