我正在尝试使用Django API使用OIDC实现Keycloak SSO。请求调用键时钟作为响应后,获取下面的错误消息
SuspiciousOperation /^oidc/回调/
在会话oidc_states__中找不到OIDC回调状态!
与我在Flask框架中所做的一样,它正在如愿以偿地工作。
请查找以下细节。
Django日志:
[20/Mar/2021 15:30:57] "GET / HTTP/1.1" 404 2229
[20/Mar/2021 15:31:03] "GET /hi HTTP/1.1" 302 0
[20/Mar/2021 15:31:03] "GET /oidcauthenticate/?next=/hi HTTP/1.1" 302 0
failed to get or create user: Claims verification failed
[20/Mar/2021 15:31:11] "GET /oidccallback/?state=UziLDF2ZcE9p2WrUIihUahgUsWdQ8zYQ&code=22d5a22b-16a6-42e3-81ba-9b569a3f1c81.2cd52631-8c4c-4f2e-a718-c908611336a3.81db1495-24af-402d-8244-a82f32bf4355 HTTP/1.1" 302 0
Not Found: /
[20/Mar/2021 15:31:11] "GET / HTTP/1.1" 404 2229设置:
Django settings for keycloakexample project.
Generated by 'django-admin startproject' using Django 3.1.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '_vg@)t*rri()^^wm7yl*i&$%gk2h1h%!xk$xms19ceb3*2z&g^'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'keycloak_oidc',
'demo',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'mozilla_django_oidc.middleware.SessionRefresh',
]
ROOT_URLCONF = 'keycloakexample.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'keycloakexample.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
from keycloak_oidc.default_settings import *
OIDC_OP_AUTHORIZATION_ENDPOINT = 'http://localhost:8080/auth/realms/aaa/protocol/openid-connect/auth'
OIDC_OP_TOKEN_ENDPOINT = 'http://localhost:8080/auth/realms/aaa/protocol/openid-connect/token'
OIDC_OP_USER_ENDPOINT = 'http://localhost:8080/auth/realms/aaa/protocol/openid-connect/userinfo'
OIDC_OP_JWKS_ENDPOINT = 'http://localhost:8080/auth/realms/aaa/protocol/openid-connect/certs'
OIDC_OP_LOGOUT_ENDPOINT = 'http://localhost:8080/auth/realms/aaa/protocol/openid-connect/logout'
AUTHENTICATION_BACKENDS = (
'keycloak_oidc.auth.OIDCAuthenticationBackend',
)
OIDC_RP_CLIENT_ID = 'test'
OIDC_RP_CLIENT_SECRET = 'd6e007e-1098-4146-a217-04e4b1d1ae9b'
# REST_FRAMEWORK = dict(
# DEFAULT_AUTHENTICATION_CLASSES=(
# 'mozilla_django_oidc.contrib.drf.OIDCAuthentication',
# 'rest_framework.authentication.SessionAuthentication'
# )
# )视图:
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
@login_required()
def hello(request):
print('123')
return HttpResponse('hello')
@login_required
def hi(request):
print('123')
return HttpResponse('hi')urls:
from django.urls import path, include
urlpatterns = [
path('oidc', include('keycloak_oidc.urls')),
path('', include('demo.urls')),
]发布于 2021-03-22 06:13:05
发布于 2022-01-11 17:46:11
发布于 2022-03-14 13:07:13
您需要添加身份验证后端类和orverride create_user方法来向True添加is_staff或is_superuser。在引用自定义类后端示例的AUTHENTICATION_BACKENDS中添加settings.py:
# auth_backends.py
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
class KeycloakOIDCAuthenticationBackend(OIDCAuthenticationBackend):
def create_user(self, claims):
""" Overrides Authentication Backend so that Django users are
created with the keycloak preferred_username.
If nothing found matching the email, then try the username.
"""
user = super(KeycloakOIDCAuthenticationBackend, self).create_user(claims)
user.first_name = claims.get('given_name', '')
user.last_name = claims.get('family_name', '')
user.email = claims.get('email')
user.is_staff = True #Here the fix that error
user.username = claims.get('preferred_username')
user.save()
return user
def filter_users_by_claims(self, claims):
""" Return all users matching the specified email.
If nothing found matching the email, then try the username
"""
email = claims.get('email')
if not email:
return self.UserModel.objects.none()
users = self.UserModel.objects.filter(email__iexact=email)
return users
def update_user(self, user, claims):
user.first_name = claims.get('given_name', '')
user.last_name = claims.get('family_name', '')
user.email = claims.get('email')
user.save()
return user在settings.py中
#settings.py
AUTHENTICATION_BACKENDS = (
'my_app.auth_backends.KeycloakOIDCAuthenticationBackend',
)https://stackoverflow.com/questions/66720512
复制相似问题