【问题标题】:Keycloak Backchannel logoutKeycloak 反向通道注销
【发布时间】:2018-10-13 01:50:52
【问题描述】:

我试图从我的 Web 应用程序中了解反向通道注销的流程,但我发现文档令人困惑。我有一个在 JBoss EAP 中运行的 JEE 应用程序,带有 Java Servlet Filter Adapter(由于某些技术原因,我不能使用 EAP 适配器)。 documentation for logging out 说:

您可以通过多种方式退出 Web 应用程序。对于 Java EE servlet 容器,可以调用 HttpServletRequest.logout()。为了 其他浏览器应用程序,您可以将浏览器重定向到 http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri,如果您与浏览器进行 SSO 会话,则会将您注销。

Admin URL configuration 的文档说:

例如,反向通道注销的工作方式是: 1.用户从一个应用程序发出注销请求 2.应用程序向Keycloak发送注销请求 3. Keycloak服务器使用户会话失效 4. Keycloak 服务器然后使用与会话关联的管理 url 向应用程序发送反向通道请求 5. 当应用程序收到注销请求时,它会使相应的 HTTP 会话失效

所以根据我的理解,要么:

  1. 调用 HttpServletRequest.logout() 应该向 Keycloak 发送请求
  2. http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri 的 GET 应该以某种方式检测到 clientId(来自重定向 URI?)并向适当的反向通道发送请求

这两个选项似乎都不适合我。在这两种情况下,我都不会收到从 Keycloak 到我的 adminUrl 的回调。此外,在调用 Request.logout() 后,我仍然在 Keycloak Admin 中看到相同数量的活动会话。根据this SO post,它似乎可以工作,但我不确定我是否缺少配置或类似的东西。

我尝试使用 access_token 将 GET 发送到注销端点,但这也没有任何区别。

我对本文档有什么误解?我应该如何编写注销代码?

【问题讨论】:

    标签: jakarta-ee keycloak


    【解决方案1】:

    普通注销和后台注销是完全不同的两件事。

    普通注销的工作原理是将浏览器重定向到您在 (2) 中提到的 URL。用户被 Keycloak 中的浏览器会话识别,因此浏览器重定向至关重要(甚至不需要提供 redirect_uri)。

    我们在 Tomcat 中通过在我们的应用程序中调用以下代码来实现这一点,该代码本身会触发重定向(当然,使用 keycloak.json 作为配置):

    Object keycloakAttr = request.getAttribute(KeycloakSecurityContext.class.getName());
    if (keycloakAttr != null && keycloakAttr instanceof RefreshableKeycloakSecurityContext) 
    {
      // code inspired by org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.logoutInternal
      RefreshableKeycloakSecurityContext ksc = (RefreshableKeycloakSecurityContext)keycloakAttr;
      KeycloakDeployment deployment = ksc.getDeployment();
      ksc.logout(deployment);
    
      // Since a CatalinaSessionTokenStore is used as token store in Tomcat
      // tokenStore.logout() is not necessary (???)
    
      request.removeAttribute(KeycloakSecurityContext.class.getName());
      request.setUserPrincipal(null);
    }
    

    反向通道注销只有在存在 多个依赖方(在 OIDC 中)或 Keycloak 发挥作用的“客户”时才有意义。它确保同一领域(对于同一用户)中的客户端的客户端会话不会“幸存”注销。

    执行上述注销后,Keycloak 检查是否存在与 Keycloak 会话关联的客户端会话,并将反向通道注销请求发送到相应的客户端(在同一领域!),因此此过程根本不涉及浏览器会话.

    为了使这项工作(对于正确安装了相应 Keycloak 适配器的 Node.js 和 Tomcat),我们只需要在 Keycloak 中正确配置客户端的 Admin URL。注意:它默认为“/”,但对于 Tomcat,必须包含 webapp 上下文,例如https://myapp.com/mywebapp/

    【讨论】:

    【解决方案2】:

    你没有使用 Keycloak 的适配器之一吗?我遇到了完全相同的问题。

    事实证明,keycloaks 自己的适配器在将代码交换为令牌时会在其 POST 中向 protocol/openid-connect/token 发送 client_session_state

    除非在token POST 中提供了这样的参数,否则不会调用 AdminURL。去搞清楚。添加该参数,它就会开始工作!

    查看相关keycloak forum post

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-08
      • 2021-04-11
      • 1970-01-01
      • 2018-07-18
      • 2016-04-18
      • 2021-04-12
      • 2018-01-04
      • 2016-02-04
      相关资源
      最近更新 更多