You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

django-saml2-auth-ai与djangosaml2集成Azure AD出现重定向循环求助

Django SAML认证重定向循环问题(已定位权限原因)

我正在为Web应用实现SAML认证,先后尝试了django-saml2-auth-ai(2.1.6)和djangosaml2(1.4.0)两个库,但均出现重定向循环问题。

django-saml2-auth-ai配置

urls.py配置

url(r'^saml2_auth/', include('django_saml2_auth.urls')),
url(r'^accounts/login/$', django_saml2_auth.views.signin, name='login'),
url(r'^accounts/logout/$', django_saml2_auth.views.signout, name='logout'),

配置文件

已将django_saml2_auth加入INSTALLED_APPS,SAML2_AUTH配置如下:

SAML2_AUTH = {
    'SAML_CLIENT_SETTINGS': {  # Pysaml2 Saml client settings
        'entityid': 'http://localhost:7000/saml2_auth/acs/',
        'metadata': {
            'local': [
                os.path.join(BASE_DIR, 'management_app/azure-ad-metadata.xml'),
            ],
        },
        'service': {
            'sp': {
                'logout_requests_signed': True,
                'idp': 'https://sts.windows.net/8d469bba-ae86-4fe1-a36d-fa9d26ec8ab6/'
            }
        }
    },
    'debug': 1,
    'DEFAULT_NEXT_URL': '/dashboard',
    'NEW_USER_PROFILE': {
        'USER_GROUPS': [],  # 新用户登录默认组
        'ACTIVE_STATUS': True,  # 新用户默认激活状态
        'STAFF_STATUS': False,  # 新用户默认员工状态
        'SUPERUSER_STATUS': False,  # 新用户默认超级用户状态
    },
    'ATTRIBUTES_MAP': {  # 映射SAML2属性到Django用户字段
        'email': 'name',
        'username': 'name',
        'first_name': 'givenname',
        'last_name': 'surname',
    },
    'ASSERTION_URL': 'http://localhost:7000',
}

Azure AD基础SAML配置

Identifier (Entity ID)                     : http://localhost:7000/saml2_auth/acs/
Reply URL (Assertion Consumer Service URL) : http://localhost:7000/saml2_auth/acs/

djangosaml2配置

urls.py配置

url(r'saml2/', include('djangosaml2.urls')),

配置文件

已将djangosaml2加入INSTALLED_APPS,添加djangosaml2.middleware.SamlSessionMiddleware到MIDDLEWARE,相关配置如下:

SAML_SESSION_COOKIE_NAME = 'saml_session'
SESSION_COOKIE_SECURE = True
SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
SAML_ATTRIBUTE_MAPPING = {
    'uid': ('username', ),
    'mail': ('email', ),
    'cn': ('first_name', ),
    'sn': ('last_name', ),
}
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'djangosaml2.backends.Saml2Backend',
)
LOGIN_URL = '/saml2/login/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
import saml2
SAML_DEFAULT_BINDING = saml2.BINDING_HTTP_POST
SAML_LOGOUT_REQUEST_PREFERRED_BINDING = saml2.BINDING_HTTP_POST
SAML_IGNORE_LOGOUT_ERRORS = True
SAML_CREATE_UNKNOWN_USER = True
SAML_USE_NAME_ID_AS_USERNAME = True
from os import path
import saml2.saml
SAML_CONFIG = {
  # xmlsec1二进制文件路径
  'xmlsec_binary': '/usr/bin/xmlsec1',

  # 实体ID
  'entityid': 'http://localhost:7000/saml2/acs/',

  # 属性映射目录
  'attribute_map_dir': path.join(BASE_DIR, 'management_app/attribute-maps'),

  # 允许未配置的属性
  'allow_unknown_attributes': True,

  # 服务配置
  'service': {
      'sp' : {
          'name': 'SP',
          'name_id_format': saml2.saml.NAMEID_FORMAT_TRANSIENT,

          'endpoints': {
              'assertion_consumer_service': [
                  ('http://localhost:7000/saml2/acs/', saml2.BINDING_HTTP_POST),
                  ('http://localhost:7000/saml2/acs/', saml2.BINDING_HTTP_REDIRECT),
              ],
              'single_logout_service': [
                  ('http://localhost:7000/saml2/ls/', saml2.BINDING_HTTP_REDIRECT),
                  ('http://localhost:7000/saml2/ls/post', saml2.BINDING_HTTP_POST),
               ],
           },

          'signing_algorithm':  saml2.xmldsig.SIG_RSA_SHA256,
          'digest_algorithm':  saml2.xmldsig.DIGEST_SHA256,

          'force_authn': False,
          'name_id_format_allow_create': False,

          'required_attributes': ['email'],
          'optional_attributes': ['surname'],

          'want_response_signed': False,
          'authn_requests_signed': False,
          'logout_requests_signed': True,
          'want_assertions_signed': True,

          'only_use_keys_in_metadata': True,
          'allow_unsolicited': True,

          'idp': {
              'https://localhost/simplesaml/saml2/idp/metadata.php': {
                  'single_sign_on_service': {
                      saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SSOService.php',
                      },
                  'single_logout_service': {
                      saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SingleLogoutService.php',
                      },
                  },
              },
          },
      },

  # 元数据配置
  'metadata': {
      'local': [path.join(BASE_DIR, 'management_app/azure-ad-metadata.xml')],
      'remote': [{"url": "https://login.microsoftonline.com/8d469bba-ae86-4fe1-a36d-fa9d26ec8ab6/federationmetadata/2007-06/federationmetadata.xml?appid=3bf6313c-fee7-4925-8c66-b94d7dc44bb3"},],
      },

  'debug': 1,

  # 签名密钥
  'key_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_private.key'),
  'cert_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_public.cert'),

  # 加密密钥
  'encryption_keypairs': [{
      'key_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_private.key'),
      'cert_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_public.cert'),
  }],

  # 联系人和组织信息
  'contact_person': [
      {'given_name': 'Lorenzo',
       'sur_name': 'Gil',
       'company': 'Yaco Sistemas',
       'email_address': 'lgs@yaco.es',
       'contact_type': 'technical'},
      {'given_name': 'Angel',
       'sur_name': 'Fernandez',
       'company': 'Yaco Sistemas',
       'email_address': 'angel@yaco.es',
       'contact_type': 'administrative'},
      ],
  'organization': {
      'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
      'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
      'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
      },
  }

Azure AD基础SAML配置

Identifier (Entity ID)                     : http://localhost:7000/saml2/acs/
Reply URL (Assertion Consumer Service URL) : http://localhost:7000/saml2/acs/

问题定位

我已确认两个库均能完成Azure AD认证,但获取令牌后陷入重定向循环。经排查,原因是:应用所需的自定义权限未被Azure AD发送,导致Django拒绝访问并重定向到登录页;但用户登录Cookie已存在,触发自动登录后再次被权限校验拒绝,形成循环。

求助

如何在用户无权限时直接显示Azure AD登录页?

内容的提问来源于stack exchange,提问作者Viktor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:27:26