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'
]

使用上述设置,我遇到了几个问题

  1. 在请求到达我的 /login Url 时从我的 SSO 服务器成功验证后 request.session 和 request.saml_session 变量都被重置,我我正在获得一个完整的新会话 ID。而且由于这个问题,我还缺少 saml_session 属性。我确实在 djangosaml2 视图中添加了一个调试点,并且在返回响应之前我可以看到存在的属性。但由于某种原因,当请求到达我的应用程序时,它正在重置。

  2. 当我尝试在 saml2/logout 上注销时,我看到以下错误:

 'NoneType' object has no attribute 'name_qualifier'

我似乎找不到我在这里缺少的东西。我已经尝试了所有我能想到的但卡住了。任何帮助是极大的赞赏。提前致谢。

我最后做了以下两件事,然后它开始为我工作

  1. 已将 djangosaml2 和 pysaml 版本分别降级到 0.19.0 和 4.9.0。

  2. 对于 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'