带有 KeycloakOpenID 的 python-keycloak 包:注销不起作用
Posted
技术标签:
【中文标题】带有 KeycloakOpenID 的 python-keycloak 包:注销不起作用【英文标题】:python-keycloak package with KeycloakOpenID : logout does not work 【发布时间】:2019-12-03 17:38:03 【问题描述】:我有一个 keycloak docker 容器(提取图像 jboss/keycloak )和一个 Django 2.2 Web 容器。对于 django 与 keycloak 的集成,使用了 social-auth-app-django
。登录工作正常。现在尝试按照此处描述的说明使用 python-keycloak 实现注销:
https://github.com/marcospereirampj/python-keycloak:
from keycloak import KeycloakOpenID
keycloak_openid = KeycloakOpenID(server_url="http://<my IP>:8080/auth/",
client_id="<client_id>",
realm_name="<my realm name>",
client_secret_key="<my secret>",
verify=True)
config_well_know = keycloak_openid.well_know()
token = keycloak_openid.token("<username>", "<password>")
print(token) # all tokens returned ok
userinfo = keycloak_openid.userinfo(token['access_token'])
print ("userinfo:", userinfo) # userinfo returned ok
keycloak_openid.logout(token['refresh_token'])
在容器日志中:
Some clients have been not been logged out for user <username> in <my realm name> realm: <client_id>
没有发生注销,仍然可以浏览网站。
缺少什么?谢谢
更新
也许我理解了这个问题。我从keycloak_openid.token()
调用获得的令牌不是在登录时为我生成的令牌。唯一可以提供给keycloak_openid.logout()
调用的令牌是原始令牌(具体来说,是令牌字典的'refresh_token' 键值)。调用keycloak_openid.refresh_token()
还会发出一个新令牌,该令牌作为注销凭据被拒绝。但是最初发布的 refresh_token 似乎没有存储在任何地方——会话、cookie 或 keycloak db。 (注意:我确实找到了access_token
,它在social_auth_usersocialauth
表的django DB 中,但我需要refresh_token
)。但是,它在登录时被转储到控制台输出,所以如果我复制它并用它调用keycloak_openid.logout()
,它会从 keycoak 注销。问题是我在哪里可以找到原始的 refresh_token?
【问题讨论】:
【参考方案1】:我曾经遇到过同样的问题。有帮助的是
-
转到
admin
页面并将您的用户定位在realm
打开浏览器的开发者控制台并监控networks
转到 keycloak 上的 sessions
选项卡,然后单击 log out
观察正在调用哪个端点,并在您的 python 后端模仿它,并在请求中使用正确的标头。
希望这会有所帮助!
【讨论】:
【参考方案2】:我知道这个问题已经过时了,但我设法退出了:
-
将以下变量添加到
settings.py
:
SOCIAL_AUTH_KEYCLOAK_LOGOUT_URL = 'https://your-keycloak/auth/realms/your-realm/openid-connect/logout'
SOCIAL_AUTH_KEYCLOAK_EXTRA_DATA=[("refresh_token","refresh_token")]
现在它将刷新令牌保存在extra_data
。
-
加入
urlpatterns
urls.py
列表中:
url(r'^logout/$', views.logout, name='logout'),
-
将带有通信代码的注销视图添加到
views.py
:
from django.contrib.auth import logout as auth_logout
import requests
def logout(request):
if request.user.is_authenticated:
user = request.user
if user.social_auth.filter(provider='keycloak'):
social = user.social_auth.get(provider='keycloak')
access_token=social.extra_data['access_token']
refresh_token=social.extra_data['refresh_token']
#logger.debug(access_token) # you can view the tokens
#logger.debug(refresh_token)
logout_request_data="client_id": settings.SOCIAL_AUTH_KEYCLOAK_KEY, "refresh_token": refresh_token, "client_secret": settings.SOCIAL_AUTH_KEYCLOAK_SECRET
headers="Authorization" : "Bearer "+access_token,"Content-Type" : "application/x-www-form-urlencoded"
result=requests.post(settings.SOCIAL_AUTH_KEYCLOAK_LOGOUT_URL,data=logout_request_data,headers=headers)
auth_logout(request)
return redirect('/')
result
成功时代码为 204。
【讨论】:
以上是关于带有 KeycloakOpenID 的 python-keycloak 包:注销不起作用的主要内容,如果未能解决你的问题,请参考以下文章