用户
控制访问系统对于防止外部来源访问是非常有效的,但Django的认证模块和用户模型紧密相连。在用户登录之后,我们需要创建一个对象在数据库中存储他们。因为LDAP搜索是不区分大小写的,默认搜索Django已经存在用户的实现使用了iexact
查询,并且使用小写的用户名来创建新用户。如果想重写这个方法,可以参考get_or_create_user()
,如果想修改代理模型,可以参考get_user_model()
。
注意:在Django1.5之前,用户对象总是User类的实例。现在的版本则支持通过修改
AUTH_USER_MODEL
来自定义用户模型。在1.1.4版本后的django-auth-ldap将遵守用户自定义的用户模型。
很明显username
是用户唯一必须的字段。默认的User类对于用户名中包含的字符有严格的限定,所以LDAPBackend
包含了2个函数ldap_to_django_username()
和django_to_ldap_username()
用来转换LDAP用户名和Django用户名。当你的LDAP用户名中包含逗点时候你或许会需要这个。你可以通过继承LDAPBackend
来实现自己的处理函数。默认情况username
是不可修改的。通过LDAPBackend
验证的用户对象将会有一个ldap_username属性,值和LDAP的用户名一样。同理,Django的username
或者get_username()
也是如此。
注意:通过
LDAPBackend
创建的用户将会被设置一个不可用的密码,这仅仅发生在用户被创建时。所以如果你在Django中设置了一个合法的用户密码,这个用户即使被LDAP拒绝,也能够通过ModelBackend
(如果配置了)登录。通常不建议这么做,除了希望某些用户在LDAP服务不可用时也能登录的情况下。
扩充用户
你可以通过 Django signals: django_auth_ldap.backend.populate_user
和django_auth_ldap.backend.populate_user_profile
来任意扩充你的用户模型,他们在用户被创建以及属性映射被应用后触发。你可以使用这点来按照你喜欢的方式从LDAP目录传递信息给用户和profile对象。用户实例将在信号处理完成时自动保存。
如果你需要的参数默认不包含在LDAP搜索结果中,请参考AUTH_LDAP_USER_ATTRLIST
。
注意:Django1.7后并不直接支持配置用户。在这些版本中,
populate_user_profile
不会被触发。
简明参数
如果你仅仅是想简单的从LDAP目录直接获取少量用户参数到Django中,可以使用AUTH_LDAP_USER_ATTR_MAP
和 AUTH_LDAP_PROFILE_ATTR_MAP
,他们使用字典来建立用户模型和LDAP服务属性名(不区分大小写)的映射:
AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn"}
AUTH_LDAP_PROFILE_ATTR_MAP = {"home_directory": "homeDirectory"}
只有字符串字段可以映射到属性上,布尔型字段可以通过组成员来定义:
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
"is_active": "cn=active,ou=groups,dc=example,dc=com",
"is_staff": ["cn=staff,ou=groups,dc=example,dc=com",
"cn=admin,ou=groups,dc=example,dc=com"],
"is_superuser": "cn=superuser,ou=groups,dc=example,dc=com"
}
AUTH_LDAP_PROFILE_FLAGS_BY_GROUP = {
"is_awesome": ["cn=awesome,ou=groups,dc=example,dc=com"]
}
如果给的是一个组构成的列表,那么所有属于这些组成员的标志都会被设置成True。
注意:Django1.7后并不直接支持配置用户。在这些版本中,
LDAPBackend
将忽视profile-related
设置。
修改用户
默认情况下,所有已经建立了映射的字段在每次用户登录时候都会被更新。想要关闭这个特性,设置AUTH_LDAP_ALWAYS_UPDATE_USER
为False即可。如果你需要在认证过程外部扩充用户——比如在用户第一次登录之前创建一个相关的模型对象,你可以调用django_auth_ldap.backend.LDAPBackend.populate_user()
,也可以创建一个LDAPBackend
对象来自由的实现所需功能。如果在LDAP服务器中不存在此用户populate_user()
函数返回None
,否则返回User
对象。
from django_auth_ldap.backend import LDAPBackend
user = LDAPBackend().populate_user('alice')
if user is None:
raise Exception('No user named alice')
直接属性访问
如果你需要访问复合属性或者有上面的情况不满足你的需求时候,你可以直接访问原生的LDAP参数。user.ldap_user
是一个拥有下列4种公共属性的对象。如果配置了组,那么组属性也是如此。
- dn: 用户的专有名称
- attrs: 用户的LDAP参数信息
- group_dns: 用户所属组的专有名称集合
- group_names: 用户所属组的简单名称集合,如果设置了
AUTH_LDAP_MIRROR_GROUPS
将会使用名字
python-ldap使用utf8编码来返回参数信息,为了方便程序将尝试使用unicode进行解码,如果解码失败则原样返回;这也许在获取类似Active Directory’s objectSid
这类二进制的属性时被使用。