带有 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

    加入urlpatternsurls.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 包:注销不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有图像处理的 REST API?

如何在 django 模板中调用带有参数的 python 函数? [复制]

带有滑块的 GRC QT GUI 范围出现错误

4.pytho while 循环

python 简单的Pytho WebSocket

实现Pytho连接Mysqln以及应用