Django用户每次登录时is_staff标志被重置如何永久设置
该问题核心原因是django-auth-ldap默认会在用户每次通过LDAP认证登录时,按照预设配置规则全量同步覆盖本地用户模型字段,如果没有在LDAP配置中声明is_staff的取值逻辑,每次登录时该字段会被默认重置为False,直接覆盖admin后台手动设置的值。
以下是三种可直接落地的解决方案,按需选择即可:
方案1:关闭LDAP用户字段自动更新(适合不需要从LDAP同步用户属性的场景)
直接在Django配置文件settings.py的LDAP配置块中添加如下配置,用户首次通过LDAP登录创建本地账号后,后续登录不会再自动覆盖本地用户的任何字段值,admin后台手动配置的is_staff、is_superuser、用户权限等内容都会永久保留:# settings.py内LDAP相关配置段 AUTH_LDAP_ALWAYS_UPDATE_USER = False注意:该配置生效后,LDAP侧的用户属性变更(如姓名、邮箱、部门字段)也不会自动同步到本地Django用户表,如果需要保留基础字段同步能力,不要选该方案。
方案2:自定义同步逻辑,保留基础字段同步仅跳过权限字段(适合需要同步LDAP基础属性的场景)
保持默认的AUTH_LDAP_ALWAYS_UPDATE_USER = True配置不变,通过信号拦截LDAP同步逻辑,避免权限字段被覆盖:- 在任意业务app的signals.py文件中添加如下信号处理代码:
from django.dispatch import receiver from django.db import transaction from django_auth_ldap.backend import populate_user @receiver(populate_user) def preserve_local_perm_flags(sender, user, ldap_user, **kwargs): # 首次创建的新用户走默认逻辑,仅处理已存在的本地用户 if not user.pk: return # 提前读取本地存储的权限字段值 staff_status = user.is_staff superuser_status = user.is_superuser # LDAP字段同步完成后还原权限配置 def restore_flags(): user.is_staff = staff_status user.is_superuser = superuser_status user.save(update_fields=["is_staff", "is_superuser"]) transaction.on_commit(restore_flags)- 在对应app的apps.py文件中注册该信号,确保服务启动时能正常加载。
方案3:配置LDAP组映射统一管控权限(适合权限由LDAP侧统一维护的场景)
如果LDAP中已经划分了系统管理员、普通用户的用户组,可以直接配置组映射规则,让is_staff权限完全由LDAP组归属决定,无需在admin后台手动修改:# settings.py内LDAP相关配置段 AUTH_LDAP_USER_FLAGS_BY_GROUP = { # 属于指定LDAP组的用户登录后自动获得is_staff权限 "is_staff": "cn=django_staff,ou=groups,dc=your-company,dc=com", "is_superuser": "cn=django_superadmin,ou=groups,dc=your-company,dc=com" }该方案下用户只要被加入对应LDAP管理员组,登录后自动带is_staff标识,移出组后登录自动收回权限,适合企业内部统一权限管控的场景。
内容的提问来源于stack exchange,提问作者gipcu

