【问题标题】:Keycloak User LogoutKeycloak 用户注销
【发布时间】:2022-02-04 23:09:43
【问题描述】:

我无法让用户从使用 Keycloak 进行访问管理的应用程序中注销。

我发现这里和那里都在讨论这个主题,但没有明确说明如何处理注销。

我试图导致用户注销,将浏览器重定向到以下格式的端点:

https://example.com/auth/realms/myrealm/protocol/openid-connect/logout?id_token_hint=mytoken&post_logout_redirect_uri=https://example.com/initialpage/

我用作“mytoken”的是我获得的向端点发出 post 请求的 access_token:

https://example.com/auth/realms/playipintern/protocol/openid-connect/token

向它传递如下参数:

grant_type="authorization_code" 
code=code_obtained_from_a_url_to_which_keycloak_redirected_the_browser 
client_id=client_id_created_using_key_cloak_gui 
redirect_uri=the_to_which_keycloak_redirected_the_browser

并阅读响应的正文。正文的内容是一个 json,如下所示:

{
    'access_token': 'long_token_I_used_latter_as_token_hint_trying_to_logout', 
    'expires_in': 300, 
    'refresh_expires_in': 1800, 
    'refresh_token': 'other_long_token', 
    'token_type': 'bearer', 
    'not-before-policy': 0, 
    'session_state': 'a_shorter_code', 
    'scope': 'email profile'
}

我的注销尝试导致 Keycloaks 日志中出现以下消息:

22:53:51,686 WARN [org.keycloak.events](默认任务 24)type=LOGOUT_ERROR,realmId=playipintern,clientId=null,userId=null,ipAddress=192.168.16.1,error=invalid_token

回复说“我们很抱歉,会话未激活”。

现在我知道我应该使用 id_token 而不是 access_token 来注销,但在 json 中没有收到 id_token。

在某个地方,有人说我应该包括在内

scope=openid

在我用来获取令牌的参数中。我做到了,希望在 json 中找到一个“id_token”字段,但没有任何改变。

据报道,其他人需要创建一个名为“openid”的范围(我相信使用 Keycloak 的 GUI)来获取令牌。这对我来说没有多大意义,但我还是尝试了它,并再次使用 Keycloak 的 GUI 将刚刚创建的范围添加到客户端范围。再一次,json 没有改变。

我尝试使用 refresh_token 作为 id_token,但这也导致了无效的令牌消息。

我不知道现在该尝试什么。任何帮助表示赞赏。

谢谢。

【问题讨论】:

  • 在从您复制访问代码的位置重定向之前,您是否将scope=openid 添加到您对http://example.com/auth/realms/playipintern/protocol/openid-connect/auth 的初始请求(注意auth 而不是末尾的`/token)?
  • 不,我没有尝试过。现在我做到了,而且效果很好。非常感谢。我认为您需要将此作为答案发布,以便我接受。

标签: oauth-2.0 keycloak openid logout


【解决方案1】:

/token 端点默认只返回访问令牌。默认情况下,成功验证后,不会返回刷新令牌,并且不会在 Keycloak 端创建用户会话。由于缺少刷新令牌,访问令牌过期时需要重新认证。但是,这种情况并不意味着 Keycloak 服务器的任何额外开销,因为默认情况下不会创建会话。

在这种情况下,注销是不必要的。但是,可以通过向 OAuth2 撤销端点发送请求来撤销已颁发的访问令牌,如 OpenID Connect 端点部分所述:

/realms/{realm-name}/protocol/openid-connect/revoke

例子:

 POST /revoke HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

 token=45ghiukldjahdnhzdauz&token_type_hint=access_token

你需要用你的令牌代替45ghiukldjahdnhzdauz

token_type_hint 可以采用access_tokenrefresh_token 作为值来定义您要撤销的令牌类型。

【讨论】:

    【解决方案2】:

    在从复制访问代码的位置重定向之前,您必须将scope=openid 添加到您对http://example.com/auth/realms/playipintern/protocol/openid-connect/auth 的初始请求(注意/auth 而不是末尾的/token)。

    您可以在this article找到更多信息和解释。

    【讨论】:

      猜你喜欢
      • 2017-07-06
      • 2019-02-24
      • 2018-03-23
      • 2022-01-19
      • 2021-06-06
      • 2018-10-13
      • 2021-05-13
      • 2019-01-19
      • 2023-02-18
      相关资源
      最近更新 更多