django 如何在反向通道注销时从Keycloak OpenID logout_token检测已登录用户?

ep6jt1vc  于 2022-12-30  发布在  Go
关注(0)|答案(1)|浏览(187)

首先让我描述一下设置:
我们有一个来自不同客户团队的前端基于Angular的产品(不是我们可以轻松修改的代码的一部分),和一个后端基于django的API服务器。
前端登录到一个keycloak服务器,当登录后,后端在每个请求中获得一个带有承载令牌的Auth头。从这里,我们能够识别登录的用户,如下所示(使用python-keycloak):

ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']

这显然是非常浪费的,因为它每次都需要额外的网络请求来进行keycloak-所以我们创建了一个django用户会话,并将其用于会话管理。
现在,当用户从前端注销时,我们需要使django会话无效。
我在keycloak领域设置中设置了“返回通道注销URL”来调用django服务器上的某个端点,该端点在注销时被调用,并在参数中得到一个“logout_token”值。
现在我不确定我应该如何根据这个令牌来识别哪个用户正在注销。
先谢了...

lymnna71

lymnna711#

我不是100%肯定你的建筑的健全性。然而,关于你的特殊问题:

ret = keycloak.userinfo(bearer_token) 
username = ret['preferred_username']

Keycloak book

    • preferred_username**这是已验证用户的用户名。应避免将此用户名作为用户的密钥,因为它可能会被更改,甚至在将来引用其他用户。相反,请始终使用用户密钥的子字段。

从OpenID连接规范中可以看出:
OP向RP发送一个类似于ID令牌的JWT,称为注销令牌,以请求它们注销。ID令牌在[OpenID.Core]的第2节中定义。
注销令牌中使用以下声明:
iss必填。颁发者标识符,(...)
sub可选。受试者标识符,(...)
和所需受众,(...)
需要iat。发布时间,(...)
jti必需。令牌的唯一标识符,(...)(...)sid(可选)。会话ID-会话的字符串标识符。它表示RP上登录的最终用户的用户代理或设备的会话。(..)
注销令牌必须包含子声明或sid声明,也可以同时包含两者。如果sid声明不存在,则目的是注销由iss和子声明标识的最终用户在RP上的所有会话。
因此,您可以尝试使用声明"sub",其中 * 是已验证用户的唯一标识符 *。您可能需要在后端创建"sub"和"user"之间的Map。或者,您可以使用相同的逻辑,但将其应用于"sid"。这样,您就可以将Keycloak的ID会话Map到您自己的ID会话。
不过,我的问题是:
前端登录到一个密钥罩服务器,登录后,后端在每个请求中获得一个带有承载令牌的Auth头。
从那个承载令牌(我假设它是一个访问令牌)中,你不能简单地从那里获得"首选用户名"(或者更好的"子"声明)吗?这不需要对Keycloak服务器进行任何额外的调用。

相关问题