首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在会话oidc_states中找不到具有keycloak - OIDC回调状态的Django-OIDC

在会话oidc_states中找不到具有keycloak - OIDC回调状态的Django-OIDC
EN

Stack Overflow用户
提问于 2021-03-20 10:28:41
回答 3查看 1.7K关注 0票数 4

我正在尝试使用Django API使用OIDC实现Keycloak SSO。请求调用键时钟作为响应后,获取下面的错误消息

SuspiciousOperation /^oidc/回调/

在会话oidc_states__中找不到OIDC回调状态!

与我在Flask框架中所做的一样,它正在如愿以偿地工作。

请查找以下细节。

Django日志:

代码语言:javascript
复制
[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

设置:

代码语言:javascript
复制
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'
#     )
# )

视图:

代码语言:javascript
复制
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:

代码语言:javascript
复制
from django.urls import path, include


urlpatterns = [
    path('oidc', include('keycloak_oidc.urls')),
    path('', include('demo.urls')),

]
EN

回答 3

Stack Overflow用户

发布于 2021-03-22 06:13:05

谢谢你的支持。

该问题已通过重新创建用户在键盘斗篷的完整细节解决。

请找到截图。密钥披风用户创建

干杯SG

票数 0
EN

Stack Overflow用户

发布于 2022-01-11 17:46:11

这里的关键问题是使用了奥伊达,特别注意AUTHENTICATION_BACKENDS。它是一个将OIDC中找到的属性与本地Django安装同步的项目,而mozilla-django-oidc只进行身份验证。上面的答案是解决这个问题的关键,一旦电子邮件地址(加上名字和姓氏)不能添加到Django中。对于没有添加这些属性的任何OIDC提供程序来说,这很可能是失败的。我在上游增加了一个问题

票数 0
EN

Stack Overflow用户

发布于 2022-03-14 13:07:13

您需要添加身份验证后端类和orverride create_user方法来向True添加is_staffis_superuser。在引用自定义类后端示例的AUTHENTICATION_BACKENDS中添加settings.py:

代码语言:javascript
复制
# 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中

代码语言:javascript
复制
#settings.py
AUTHENTICATION_BACKENDS = (
    'my_app.auth_backends.KeycloakOIDCAuthenticationBackend',
)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66720512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档