Невозможно выйти из IDC keycloak изнутри кода приложения Django. Все ответы на вопросы stackoverflow не сработали (большинство из них для более старых версий задействованных компонентов), то же самое относится и к документации по keycloak.
Недавно мы внедрили аутентификацию на основе keycloak для нашего сайта на Django. Работает нормально для аутентификации. Приложение построено на Docker, три контейнера: веб-сайт на порту 8000, keycloak db (образ postgres), keycloak (образ jboss / keycloak) на порту 8080.
Теперь мне нужно добавить функцию «Выход» вэто означает выделение клавиатуры из моего кода Django и перенаправление пользователя обратно на экран регистрации клавиатуры.
Моя настройка:
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
с идентификатором пользователя и именем области.
Это возвращает 403 и ошибку: «Запрещено (файл cookie CSRF не установлен.): / {Имя области} / пользователи / {идентификатор пользователя} / logout /»
urls. py
urlpaterns = [
....
url(r'logout/$', logout_view, name='logout'),
...
]
views.py
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")
Это возвращает меня на главную страницу моего сайта, я все еще вошел в систему и могу просматриватьсайт нормально. Нажатие на экран входа в систему Keycloak в этот момент возвращает меня на мою первую страницу веб-сайта, на которой вы уже авторизованы, так что я все еще аутентифицирован. Сеанс убийства перед кодом POST в Django ничего не меняет. По сути, нет выхода ни из websste, ни из keycloak, когда я проходил аутентификацию через keycloak. Истечение срока действия Keycloak происходит со временем, поэтому настройки realm.json работают.
Я пытался установить это в моих settings.py:
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_SECURE = False
.. но безрезультатно.
Итак, где я могу найти пример работающего кода Django, который отключает пользователя от Keycloak? Спасибо
Другие произведения (вероятно, неактуальные):
settings.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',
)
....
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
keycloak / 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
}