如何从Django代码中从KeyClope注销
无法从Django应用程序代码内部从KeyClope IDP注销。所有的stackoverflow答案对我来说都不起作用(大多数是针对所涉及组件的旧版本),KeyClope文档也是如此 最近,我们已经为基于Django的网站实现了基于Key斗篷的感知。对auth来说很好。 该应用程序由docker构建,有三个容器:8000端口上的网站、8080端口上的Keyclope db(postgres图像)、Keyclope(jboss/Keyclope图像) 现在,我必须向它添加“注销”功能,这意味着从我的Django代码中唱出keydove,并将用户重定向回keydove登录屏幕 我的设置:如何从Django代码中从KeyClope注销,django,realm,keycloak,logout,idp,Django,Realm,Keycloak,Logout,Idp,无法从Django应用程序代码内部从KeyClope IDP注销。所有的stackoverflow答案对我来说都不起作用(大多数是针对所涉及组件的旧版本),KeyClope文档也是如此 最近,我们已经为基于Django的网站实现了基于Key斗篷的感知。对auth来说很好。 该应用程序由docker构建,有三个容器:8000端口上的网站、8080端口上的Keyclope db(postgres图像)、Keyclope(jboss/Keyclope图像) 现在,我必须向它添加“注销”功能,这意味着从
Django 2.2
Python 3.5
keycloak 7
social-auth-app-django 3.1.0
social-auth-core 3.2.0
建议如下:
POST/{realm}/users/{id}/logout
具有用户id和领域名称
这只产生404,所以我切换到这个模式(喜欢stackoverflow):
POST/auth/realms/acc/protocol/openid连接/注销
这将返回403和错误:
“禁止(未设置CSRF cookie):/{realm name}/users/{user id}/logout/”
我设法解决了这个问题(见下面的更新)
url.py
urlpaterns = [
....
url(r'logout/$', logout_view, name='logout'),
...
]
from django.http import HttpResponseRedirect
import requests
def logout_view(request):
url = '%s<realm name>/users/<user id>/logout/' % settings.LOGOUT_REDIRECT_URL
r = requests.post(url, data = {})
#r.status_code at this point is 403
#also tried another sugestion:
url = '%sauth/realms/%s/protocol/openid-connect/logout/' % (settings.LOGOUT_REDIRECT_URL, '<some realm name>')
r = requests.post(url, data = {})
#r.status_code at this point is 403
#also tried with refresh_token and client_id:
url = "http://<website ip>:8000/<realm name>/users/<user id>/logout/"
refresh_token = '<some refresh token pulled out from stout>'
r = requests.post(url, data = {'refresh_token': refresh_token, 'client_id': '<user id>'})
#for 'client_id' above tried both user id and user name
#r.status_code at this point is also 403
return HttpResponseRedirect("http://<website ip>:8000")
视图.py
urlpaterns = [
....
url(r'logout/$', logout_view, name='logout'),
...
]
from django.http import HttpResponseRedirect
import requests
def logout_view(request):
url = '%s<realm name>/users/<user id>/logout/' % settings.LOGOUT_REDIRECT_URL
r = requests.post(url, data = {})
#r.status_code at this point is 403
#also tried another sugestion:
url = '%sauth/realms/%s/protocol/openid-connect/logout/' % (settings.LOGOUT_REDIRECT_URL, '<some realm name>')
r = requests.post(url, data = {})
#r.status_code at this point is 403
#also tried with refresh_token and client_id:
url = "http://<website ip>:8000/<realm name>/users/<user id>/logout/"
refresh_token = '<some refresh token pulled out from stout>'
r = requests.post(url, data = {'refresh_token': refresh_token, 'client_id': '<user id>'})
#for 'client_id' above tried both user id and user name
#r.status_code at this point is also 403
return HttpResponseRedirect("http://<website ip>:8000")
…但没有效果
那么,我在哪里可以找到一个使用Django代码的示例,该代码可以让用户从KeyClope注销?谢谢
更新
谜题的第一部分已经解决了(阅读,答案由和类似的帖子):为了摆脱“CSRF cookie not set”错误,我必须做一件简单的事情:
from django.views.decorators.csrf import csrf_exempt
并为我的注销视图添加装饰器:
@csrf_exempt
def logout_view(request):
..........
之后,执行注销请求,并返回以下内容:
[org.keycloak.events] (default task-12) type=LOGOUT_ERROR, realmId=acclims, clientId=63cb82ff-17f4-4f2d-95e1-a8b3c742e28b, userId=null, ipAddress=172.22.0.1, error=invalid_client_credentials
status_code: 400
我猜我没有发回正确的刷新令牌,我不知道如何测试这种怀疑
-------------------------------------------------------
其他部分(可能不相关):
设置.py
.....
LOGIN_URL = SCRIPT_NAME + '/login/keycloak'
#yes, I tried this:
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_SECURE = False
SOCIAL_AUTH_KEYCLOAK_KEY = '<some keycloak key>'
SOCIAL_AUTH_KEYCLOAK_SECRET = 'some keycloak secret'
SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY = 'some public key'
SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL = 'http://<some ip>:8080/auth/realms/<some realm>/protocol/openid-connect/auth'
SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL = 'http://<some ip>:8080/auth/realms/<some realm>/protocol/openid-connect/token'
SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy'
SOCIAL_AUTH_STORAGE = 'social_django.models.DjangoStorage'
SOCIAL_AUTH_KEYCLOAK_ID_KEY = 'email'
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
SOCIAL_AUTH_URL_NAMESPACE = 'social'
LOGIN_REDIRECT_URL = 'http://<website ip>:8000/'
LOGOUT_REDIRECT_URL = 'http://<website ip>:8000/'
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.mail.mail_validation',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.debug.debug',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'social_core.pipeline.debug.debug',
)
....
。。。。。
LOGIN\u URL=SCRIPT\u NAME+'/LOGIN/keydave'
#是的,我试过这个:
CSRF\u COOKIE\u SECURE=False
会话\u COOKIE\u SECURE=False
社交身份验证密钥伪装密钥=“”
SOCIAL_AUTH_keydove_SECRET='some keydove SECRET'
社交密钥(AUTH)密钥(keydape)(PUBLIC)="某些公钥"
社交身份验证密钥伪装授权URL='http://:8080/AUTH/realms//protocol/openid connect/AUTH'
社交身份验证密钥伪装访问令牌URL='http://:8080/AUTH/realms//protocol/openid connect/TOKEN'
SOCIAL_AUTH_STRATEGY='SOCIAL_django.STRATEGY.DjangoStrategy'
SOCIAL_AUTH_STORAGE='SOCIAL_django.models.DjangoStorage'
社交身份验证密钥伪装ID密钥='email'
社交网站(AUTH\u POSTGRES\u JSONFIELD)=True
社交\u身份验证\u URL\u命名空间='SOCIAL'
登录\重定向\ URL='http://:8000/'
注销\u重定向\u URL='http://:8000/'
社交网站(AUTH\u POSTGRES\u JSONFIELD)=True
社会认证管道=(
“社交核心.管道.社交授权.社交详细信息”,
“social_core.pipeline.social_auth.social_uid”,
“允许社交核心.管道.社交身份验证.身份验证”,
“social_core.pipeline.social_auth.social_user”,
“social_core.pipeline.user.get_username”,
“social_core.pipeline.mail.mail_验证”,
“social_core.pipeline.user.create_user”,
“社交核心.pipeline.socialauth.associate用户”,
“social_core.pipeline.debug.debug”,
“社交核心.管道.社交身份验证.加载额外数据”,
“social_core.pipeline.user.user_details”,
“social_core.pipeline.debug.debug”,
)
....
docker compose.yml
version: '3'
services:
web:
restart: unless-stopped
container_name: web-container
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
environment:
PRODUCTION: 'false'
DEBUG: 'True'
DJANGO_SETTINGS_MODULE: '<something>.settings.postgres'
DB_NAME: '<some name>'
DB_USER: '<some user>'
DB_PASS: '<some password>'
DB_HOST: '<some host>'
depends_on:
- db
volumes:
- ./:/usr/src/app/
db:
image: postgres:9.6.2
# volumes:
# - ../docker-postgresql-multiple-databases:/docker-entrypoint-initdb.d
volumes:
- data:/var/lib/postgresql/data
environment:
- POSTGRES_MULTIPLE_DATABASES=<something>
- POSTGRES_USER=<some user>
- POSTGRES_PASSWORD=<some password>
keycloakdb:
image: postgres
volumes:
- keycloak_postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: jboss/keycloak
command: -b 0.0.0.0 -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/tmp/
environment:
DB_VENDOR: POSTGRES
DB_ADDR: keycloakdb
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: <some password>
KEYCLOAK_USER: <some user>
KEYCLOAK_PASSWORD: <some password>
#KEYCLOAK_IMPORT: /tmp/
ports:
- 8080:8080
volumes:
- ./keycloak/:/tmp/
depends_on:
- keycloakdb
volumes:
data:
# external: true
keycloak_postgres_data:
driver: local
版本:“3”
服务:
网状物:
重新启动:除非停止
容器名称:web容器
建造:
上下文:。
dockerfile:dockerfile.dev
端口:
- "8000:8000"
环境:
制作:'假'
调试:“True”
DJANGO_设置_模块:'.SETTINGS.postgres'
数据库名称:“”
DB\u用户:“”
DB_通行证:“”
DB\u主机:“”
取决于:
-分贝
卷数:
-./:/usr/src/app/
db:
图片:postgres:9.6.2
#卷数:
#-../docker postgresql多数据库:/docker entrypoint initdb.d
卷数:
-数据:/var/lib/postgresql/data
环境:
-POSTGRES\u多个\u数据库=
-POSTGRES_用户=
-POSTGRES_密码=
keydb:
图片:博士后
卷数:
-keydape\u postgres\u data:/var/lib/postgresql/data
环境:
博士后:钥匙斗篷
POSTGRES_用户:密钥斗篷
POSTGRES_密码:PASSWORD
钥匙斗篷:
图片:jboss/keydape
命令:-b 0.0.0.0-dkeydepose.migration.action=import-dkeydepose.migration.provider=dir-dkeydepose.migration.dir=/tmp/
环境:
DB_供应商:POSTGRES
数据库地址:keydavepdb
DB_数据库:密钥斗篷
DB_用户:密钥斗篷
DB_模式:公共
DB_密码:
密钥斗篷用户:
密钥隐藏密码:
#keydove\u导入:/tmp/
端口:
- 8080:8080
卷数:
-./keydove/:/tmp/
取决于:
-密钥隐藏数据库
卷数:
数据:
#外部:正确
密钥斗篷\u postgres\u数据:
司机:本地
keydape/realm.json
{
"id" : "<some realm id>",
"realm" : "<some realm name>",
"notBefore" : 0,
"revokeRefreshToken" : false,
"refreshTokenMaxReuse" : 0,
"accessTokenLifespan" : 300,
"accessTokenLifespanForImplicitFlow" : 900,
"ssoSessionIdleTimeout" : 1800,
"ssoSessionMaxLifespan" : 36000,
"ssoSessionIdleTimeoutRememberMe" : 0,
"ssoSessionMaxLifespanRememberMe" : 0,
"offlineSessionIdleTimeout" : 2592000,
"offlineSessionMaxLifespanEnabled" : false,
"offlineSessionMaxLifespan" : 5184000,
"accessCodeLifespan" : 60,
"accessCodeLifespanUserAction" : 300,
"accessCodeLifespanLogin" : 1800,
"actionTokenGeneratedByAdminLifespan" : 43200,
"actionTokenGeneratedByUserLifespan" : 300,
"enabled" : true,
"sslRequired" : "external",
"registrationAllowed" : false,
"registrationEmailAsUsername" : false,
"rememberMe" : false,
"verifyEmail" : false,
"loginWithEmailAllowed" : true,
"duplicateEmailsAllowed" : false,
"resetPasswordAllowed" : false,
"editUsernameAllowed" : false,
"bruteForceProtected" : false,
"permanentLockout" : false,
"maxFailureWaitSeconds" : 900,
"minimumQuickLoginWaitSeconds" : 60,
"waitIncrementSeconds" : 60,
"quickLoginCheckMilliSeconds" : 1000,
"maxDeltaTimeSeconds" : 43200,
"failureFactor" : 30,
"roles" : {
....bunch of roles
}
{
“id”:“,
“领域”:“,
“notBefore”:0,
“revokeRefreshToken”:false,
“refreshTokenMaxReuse”:0,
“寿命”:300,
“accessTokenLifespanForImplicitFlow”:900,
“ssoSessionIdleTimeout”:1800,
“ssoSessionMaxLifespan”:36000,
“SSOSessionDLeTimeoutMemberme”:0,
“SSOSessionMaxLifeSpanMemberme”:0,
“offlineSessionIdleTimeout”:2592000,
“offlineSessionMaxLifespanEnabled”:false,
“offlineSessionMaxLifespan”:5184000,
“使用寿命”:60,
“accessCodeLifespanUserAction”:300,
“accessCodeLifespanLogin”:1800,
“actionTokenGeneratedByAdminLifespan”:43200,
“actionTokenGeneratedByUserLifespan”:300,
“启用”:正确,
“sslRequired”:“外部”,
“RegistrationLowed”:错误,
“RegistrationMailAsUserName”:false,
“记住”:错,
“验证电子邮件”:false,
“loginWithEmailAllowed”:true,
“重复:错误,
“resetPasswordAllowed”:false,
“EditUserName允许