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

Django auth_adfs配置求助:内外用户鉴权冲突及#EXT#错误

解决Django + django_auth_adfs 内外用户认证兼容方案

核心思路是放弃单一的USERNAME_CLAIM配置,自定义用户名解析逻辑,同时调整Django用户模型的验证规则,兼容内部用户和带#EXT#后缀的外部用户令牌。

1. 自定义用户名解析函数

在项目中创建工具模块(如adfs_utils.py),编写从JWT令牌claims中提取合法用户名的逻辑:

def get_username_from_claims(claims):
    # 优先处理upn,移除外部用户的#EXT#后缀
    if 'upn' in claims:
        upn = claims['upn']
        return upn.replace('#EXT#', '') if '#EXT#' in upn else upn
    # 降级使用email,兼容部分内部用户场景
    elif 'email' in claims:
        return claims['email']
    # 兜底用sub(Azure AD唯一用户标识),避免认证失败
    return claims['sub']

在settings.py中配置django_auth_adfs使用该函数:

AUTH_ADFS = {
    # 保留原有其他配置(如CLIENT_ID、TENANT_ID等)
    'USERNAME_CLAIM': None,  # 禁用默认单一claim解析
    'CUSTOM_USERNAME_CLAIM_PROVIDER': 'your_project.adfs_utils.get_username_from_claims',
}

2. 调整Django用户模型的用户名验证规则

默认Django用户名不允许包含@、#等字符,需修改用户模型适配:

方案A:使用自定义用户模型

在应用的models.py中定义自定义用户模型:

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    username = models.CharField(
        max_length=255,
        unique=True,
        help_text="支持包含@、.等字符的用户名",
        validators=[],  # 清空默认用户名验证器,允许更多字符
    )

在settings.py指定自定义用户模型:

AUTH_USER_MODEL = 'your_app.CustomUser'

注意:若已有用户数据,需执行数据迁移命令python manage.py makemigrations和python manage.py migrate,确保数据兼容。

方案B:修改默认用户模型的验证器(仅临时场景)

若不想替换用户模型,可通过修改全局验证器实现:

# 在项目初始化文件(如apps.py)中修改
from django.contrib.auth.validators import UnicodeUsernameValidator
UnicodeUsernameValidator.regex = r'^[\w.@+-]+$'

3. 确认Azure AD应用注册配置

  • 进入Azure门户的应用注册页面,在「令牌配置」中添加upn和email作为可选声明并启用
  • 确保应用的「支持的账户类型」设置为「任何组织目录中的账户和个人Microsoft账户」(按需调整,若仅需企业外部用户可选择对应选项)

4. 验证测试

  • 分别使用内部域用户和外部注册用户登录系统,检查用户对象的username字段是否正确解析
  • 测试后端API接口,确认两类用户均能正常访问,无401或500错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:12:45