Django saml2 登录缺少会话变量
Django saml2 login missing session variables
对于我的 Django 应用程序,我正在尝试使用 Djangosaml2 启用 SSO,以下是我正在使用的版本
djangosaml2==1.2.0
pysaml2==7.0.0
djangorestframework==3.12.2
Django==3.1.7
python==3.8
我的saml2_settings如下
from os import path
import saml2
import saml2.saml
from app.local_settings import SERVER_URL
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'djangosaml2.backends.Saml2Backend',
)
SAML_SESSION_COOKIE_NAME = 'saml_session'
SAML_ATTRIBUTE_MAPPING = {
'username': ('username', ),
'email': ('email', ),
'first_name': ('first_name', ),
'last_name': ('last_name', ),
}
BASEDIR = path.dirname(path.abspath(__file__))
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
LOGIN_URL = '/saml2/login/'
LOGOUT_URL = '/saml2/logout/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SAML_CREATE_UNKNOWN_USER = True
SAML_SERVER_URL = '10.23.1.114'
SAML_ENABLED = True
# MIDDLEWARE.append('djangosaml2.middleware.SamlSessionMiddleware')
SAML_CONFIG = {
# full path to the xmlsec1 binary programm
'xmlsec_binary': '/usr/bin/xmlsec1',
# your entity id, usually your subdomain plus the url to the metadata view
'entityid': path.join(SAML_SERVER_URL, 'saml2/metadata'),
# directory with attribute mapping
'attribute_map_dir': path.join(BASEDIR, 'attribute_maps'),
# this block states what services we provide
'service': {
# we are just a lonely SP
'sp' : {
'name': 'Dummy app',
'allow_unsolicited': True,
'authn_requests_signed': True,
'force_authn': True,
'want_response_signed': True,
'want_assertions_signed': True,
'logout_requests_signed': True,
'name_id_format_allow_create': False,
'endpoints': {
# url and binding to the assetion consumer service view
# do not change the binding or service name
'assertion_consumer_service': [
(path.join(SAML_SERVER_URL, 'saml2/acs/'),
saml2.BINDING_HTTP_POST),
],
# url and binding to the single logout service view
# do not change the binding or service name
'single_logout_service': [
(path.join(SAML_SERVER_URL, 'saml2/ls/'),
saml2.BINDING_HTTP_REDIRECT),
(path.join(SAML_SERVER_URL, 'saml2/ls/post/'),
saml2.BINDING_HTTP_POST),
],
},
},
},
# where the remote metadata is stored, local, remote or mdq server.
# One metadatastore or many ...
'metadata': {
'local': [path.join(BASEDIR, 'idp_metadata.xml')]
},
# Signing
'key_file': path.join(BASEDIR, 'samlkey.key'), # private part
'cert_file': path.join(BASEDIR, 'samlcert.pem'), # public part
# own metadata settings
'contact_person': [
{'given_name': '--',
'company': '--',
'email_address': '--',
'contact_type': '--'}
],
# you can set multilanguage information here
'organization': {
'name': [('--', 'en')],
'display_name': [('--', 'en')],
'url': [('--', 'en')],
},
"valid_for": 24
}
我的中间件如下:
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.security.SecurityMiddleware',
'user_sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app.middleware.APPMiddleware',
'djangosaml2.middleware.SamlSessionMiddleware'
]
使用上述设置,我遇到了几个问题
在请求到达我的 /login Url 时从我的 SSO 服务器成功验证后 request.session 和 request.saml_session 变量都被重置,我我正在获得一个完整的新会话 ID。而且由于这个问题,我还缺少 saml_session 属性。我确实在 djangosaml2 视图中添加了一个调试点,并且在返回响应之前我可以看到存在的属性。但由于某种原因,当请求到达我的应用程序时,它正在重置。
当我尝试在 saml2/logout 上注销时,我看到以下错误:
'NoneType' object has no attribute 'name_qualifier'
我似乎找不到我在这里缺少的东西。我已经尝试了所有我能想到的但卡住了。任何帮助是极大的赞赏。提前致谢。
我最后做了以下两件事,然后它开始为我工作
已将 djangosaml2 和 pysaml 版本分别降级到 0.19.0 和 4.9.0。
对于 HTTPS 连接,添加 SESSION_COOKIE_SECURE = True,对于开发即 运行 服务器案例,SESSION_COOKIE_SECURE = False 在您的 settings.py
我正在将 Django 从 1.1 迁移到 3.1。您的代码库实际上解决了我的问题。我在 saml/config.py
:
中添加了 SESSION_SERIALIZER
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
并在settings.py
中添加了SamlSessionMiddleware
:
djangosaml2.middleware.SamlSessionMiddleware
我的问题是:
'WSGIRequest' object has no attribute 'saml session'
对于我的 Django 应用程序,我正在尝试使用 Djangosaml2 启用 SSO,以下是我正在使用的版本
djangosaml2==1.2.0
pysaml2==7.0.0
djangorestframework==3.12.2
Django==3.1.7
python==3.8
我的saml2_settings如下
from os import path
import saml2
import saml2.saml
from app.local_settings import SERVER_URL
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'djangosaml2.backends.Saml2Backend',
)
SAML_SESSION_COOKIE_NAME = 'saml_session'
SAML_ATTRIBUTE_MAPPING = {
'username': ('username', ),
'email': ('email', ),
'first_name': ('first_name', ),
'last_name': ('last_name', ),
}
BASEDIR = path.dirname(path.abspath(__file__))
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
LOGIN_URL = '/saml2/login/'
LOGOUT_URL = '/saml2/logout/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SAML_CREATE_UNKNOWN_USER = True
SAML_SERVER_URL = '10.23.1.114'
SAML_ENABLED = True
# MIDDLEWARE.append('djangosaml2.middleware.SamlSessionMiddleware')
SAML_CONFIG = {
# full path to the xmlsec1 binary programm
'xmlsec_binary': '/usr/bin/xmlsec1',
# your entity id, usually your subdomain plus the url to the metadata view
'entityid': path.join(SAML_SERVER_URL, 'saml2/metadata'),
# directory with attribute mapping
'attribute_map_dir': path.join(BASEDIR, 'attribute_maps'),
# this block states what services we provide
'service': {
# we are just a lonely SP
'sp' : {
'name': 'Dummy app',
'allow_unsolicited': True,
'authn_requests_signed': True,
'force_authn': True,
'want_response_signed': True,
'want_assertions_signed': True,
'logout_requests_signed': True,
'name_id_format_allow_create': False,
'endpoints': {
# url and binding to the assetion consumer service view
# do not change the binding or service name
'assertion_consumer_service': [
(path.join(SAML_SERVER_URL, 'saml2/acs/'),
saml2.BINDING_HTTP_POST),
],
# url and binding to the single logout service view
# do not change the binding or service name
'single_logout_service': [
(path.join(SAML_SERVER_URL, 'saml2/ls/'),
saml2.BINDING_HTTP_REDIRECT),
(path.join(SAML_SERVER_URL, 'saml2/ls/post/'),
saml2.BINDING_HTTP_POST),
],
},
},
},
# where the remote metadata is stored, local, remote or mdq server.
# One metadatastore or many ...
'metadata': {
'local': [path.join(BASEDIR, 'idp_metadata.xml')]
},
# Signing
'key_file': path.join(BASEDIR, 'samlkey.key'), # private part
'cert_file': path.join(BASEDIR, 'samlcert.pem'), # public part
# own metadata settings
'contact_person': [
{'given_name': '--',
'company': '--',
'email_address': '--',
'contact_type': '--'}
],
# you can set multilanguage information here
'organization': {
'name': [('--', 'en')],
'display_name': [('--', 'en')],
'url': [('--', 'en')],
},
"valid_for": 24
}
我的中间件如下:
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.security.SecurityMiddleware',
'user_sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app.middleware.APPMiddleware',
'djangosaml2.middleware.SamlSessionMiddleware'
]
使用上述设置,我遇到了几个问题
在请求到达我的 /login Url 时从我的 SSO 服务器成功验证后 request.session 和 request.saml_session 变量都被重置,我我正在获得一个完整的新会话 ID。而且由于这个问题,我还缺少 saml_session 属性。我确实在 djangosaml2 视图中添加了一个调试点,并且在返回响应之前我可以看到存在的属性。但由于某种原因,当请求到达我的应用程序时,它正在重置。
当我尝试在 saml2/logout 上注销时,我看到以下错误:
'NoneType' object has no attribute 'name_qualifier'
我似乎找不到我在这里缺少的东西。我已经尝试了所有我能想到的但卡住了。任何帮助是极大的赞赏。提前致谢。
我最后做了以下两件事,然后它开始为我工作
已将 djangosaml2 和 pysaml 版本分别降级到 0.19.0 和 4.9.0。
对于 HTTPS 连接,添加 SESSION_COOKIE_SECURE = True,对于开发即 运行 服务器案例,SESSION_COOKIE_SECURE = False 在您的 settings.py
我正在将 Django 从 1.1 迁移到 3.1。您的代码库实际上解决了我的问题。我在 saml/config.py
:
SESSION_SERIALIZER
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
并在settings.py
中添加了SamlSessionMiddleware
:
djangosaml2.middleware.SamlSessionMiddleware
我的问题是:
'WSGIRequest' object has no attribute 'saml session'