认证
服务端配置
如果你的LDAP服务器不是运行在本机以及默认端口,你需要设置AUTH_LDAP_SERVER_URI
来指明这些信息。这些可以被设定为任何你所使用的LDAP库支持的值。比如openldap准许你使用逗号或空格分割的URL列表。
AUTH_LDAP_SERVER_URI = "ldap://ldap.example.com"
如果你的LDAP服务器URL是动态的并且十分灵活(译者注:意思就是URL在不同情况下会有不同的值),你可以提供一个函数(或者任何可调用对象)来返回URL。你应该假设每次请求这个函数都会被调用,这是一种昂贵的开销,所以需要缓存来减少开销。
from my_module import find_my_ldap_server
AUTH_LDAP_SERVER_URI = find_my_ldap_server
如果你需要配置任何关于python-ldap的选项,可以设置AUTH_LDAP_GLOBAL_OPTIONS
和/或 AUTH_LDAP_CONNECTION_OPTIONS
。比如禁用referral这种不常见的情况:
import ldap
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0
}
搜索绑定
现在你可以和LDAP服务器进行通讯了,下一步就是验证用户名和密码。这里有2种方法:搜索式绑定和直接绑定。第一种方式要么涉及匿名账户要么涉及固定账户并且通过DN(distinguished name)搜索用户,然后进行密码验证来绑定用户。第二种方式直接在用户名中指明DN并且尝试直接绑定用户。
因为LDAP的搜索配置在其他地方,所以提供了LDAPSearch
来对搜索信息进行封装。在这里,过滤参数应该包含%(user)s
占位符。一个简单的搜索绑定配置如下(为了完整性而包含了一些默认值):
import ldap
from django_auth_ldap.config import LDAPSearch
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
联合搜索
1.1版新功能
如果你需要从多个地方来搜索用户,你可以使用LDAPSearchUnion
。这需要多个LDAPSearch
对象并返回结果的集合,默认情况并没指定搜索的优先级:
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion
AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(
LDAPSearch("ou=users,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"),
LDAPSearch("ou=otherusers,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"),
)
直接绑定
省略搜索过程,直接指定AUTH_LDAP_USER_DN_TEMPLATE
来构造用户的DN信息,这里应该有占位符%(user)s
,如果上面的例子中使用了ldap.SCOPE_ONELEVEL
,那么下面的写法更加直接高效:
AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
注意
LDAP在匹配用户DN信息时候是十分灵活的,LDAPBackend
通过在创建django用户时候强制把用户名转换成小写并去除空格来适应这种灵活性。
有些LDAP配置准许用户没有密码,为了防止出错,LDAPBackend
默认拒绝任何没有密码的验证请求。你可以通过设置AUTH_LDAP_PERMIT_EMPTY_PASSWORD = True
来关闭这一特性。
默认情况下,对LDAP所有的操作都是以AUTH_LDAP_BIND_DN
和AUTH_LDAP_BIND_PASSWORD
设定的帐号进行的而不是当前用户的。否则LDAP将在登录请求时使用正在验证的用户凭证绑定,而其他请求使用默认用户的凭证。所以根据djanog view的不同你也许会看到不同的LDAP参数。如果你愿意为了获取绑定时用户的参数而接受这种不一致,可以设置AUTH_LDAP_BIND_AS_AUTHENTICATING_USER
参数。
默认情况下,LDAP链接是未加密的并且不尝试去保护比如密码一类的敏感信息。如果和本地网络进行LDAP通讯也许没问题,如果需要进行安全链接你可以使用ldaps://
前缀或者启用StartTLS扩展。一般情况下推荐后者:
AUTH_LDAP_START_TLS = True
如果LDAPBackend
收到了python_ldap引发的LDAPError
错误,一般情况下仅会记录下这个错误到日志中,如果你需要任何特殊的处理,可以添加信号处理代码到django_auth_ldap.backend.ldap_error
中。这个信号处理代码可以用任何你喜欢的方式处理异常,包括引发其他异常等。