[英]Get LDAP group based on login username in Django
I need to retrieve the list of groups a user is in, using an LDAP query in Django. 我需要使用Django中的LDAP查询来检索用户所在的群组列表。 The use case is: a user fills in his LDAP login credentials, and Django will authenticate him and will also assign his LDAP groups .
用例是:用户填写其LDAP登录凭据,并且Django将对其进行身份验证,并将分配其LDAP组 。
The user login works flawlessly, but I cannot filter groups using memberUid=%(user)s
. 用户登录可以正常工作,但是我无法使用
memberUid=%(user)s
过滤组。 I'm looking for the right method to pass the username as a filter argument to "groupfilter" property . 我正在寻找将用户名作为过滤器参数传递给“ groupfilter”属性的正确方法 。 I tested the query with an LDAP application browser and seems to work properly.
我使用LDAP应用程序浏览器测试了查询,并且似乎可以正常工作。
I'm using RatticWeb django application to manage users' passwords with the following local configuration (see also Rattic repository wiki ): 我正在使用RatticWeb django应用程序通过以下本地配置来管理用户的密码(另请参见Rattic存储库Wiki ):
conf/local.cfg CONF / local.cfg
[ldap]
requirecert = True
# LDAP server details
uri = ldap://localhost:port
# Bind DN
binddn = cn=admin,dc=mydomain
bindpw = mypassword
# User parameters
userbase = ou=Users,dc=mydomain
userfilter = (uid=%(user)s)
#userfilter = (objectClass=person)
userfirstname = givenName
userlastname = sn
useldapgroups = True
# Set up the basic group parameters.
groupbase = ou=Groups,dc=mydomain
groupfilter = (&(objectClass=posixGroup)(memberUid=%(user)s))
grouptype = PosixGroupType
# How do I find staff
#staff = cn=staff,ou=groups,dc=example,dc=com
loglevel = DEBUG
This configuration file is read by settings.py ( source code ): 该配置文件由settings.py ( 源代码 )读取:
ratticweb/settings.py ratticweb / settings.py
# Defaults to a bogus filter so that searching yields no errors in the log
AUTH_LDAP_GROUP_FILTER = confget('ldap', 'groupfilter', '(objectClass=_fake)')
AUTH_LDAP_USER_SEARCH = LDAPSearch(AUTH_LDAP_USER_BASE, ldap.SCOPE_SUBTREE, AUTH_LDAP_USER_FILTER)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(AUTH_LDAP_GROUP_BASE, ldap.SCOPE_SUBTREE, AUTH_LDAP_GROUP_FILTER)
Now, I need to filter LDAP group passing the username parameter coming from user login form, and I tried using the same format of userfilter but the server give me back the following error: 现在,我需要过滤传递来自用户登录表单的username参数的LDAP组,并且尝试使用相同格式的userfilter,但服务器将以下错误返回给我:
[Wed Jan 13 16:51:24.257325 2016] [:error] [pid 11280] 2016-01-13 16:51:24,256 [ERROR] Caught Exception while authenticating myusername
[Wed Jan 13 16:51:24.257438 2016] [:error] [pid 11280] Traceback (most recent call last):
[Wed Jan 13 16:51:24.257478 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py", line 323, in authenticate
[Wed Jan 13 16:51:24.257515 2016] [:error] [pid 11280] self._get_or_create_user()
[Wed Jan 13 16:51:24.257550 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py", line 539, in _get_or_create_user
[Wed Jan 13 16:51:24.257586 2016] [:error] [pid 11280] self._mirror_groups()
[Wed Jan 13 16:51:24.257620 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py", line 638, in _mirror_groups
[Wed Jan 13 16:51:24.257697 2016] [:error] [pid 11280] group_names = self._get_groups().get_group_names()
[Wed Jan 13 16:51:24.257734 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py", line 755, in get_group_names
[Wed Jan 13 16:51:24.257770 2016] [:error] [pid 11280] group_infos = self._get_group_infos()
[Wed Jan 13 16:51:24.257804 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/backend.py", line 803, in _get_group_infos
[Wed Jan 13 16:51:24.257835 2016] [:error] [pid 11280] self._group_search)
[Wed Jan 13 16:51:24.257864 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/config.py", line 374, in user_groups
[Wed Jan 13 16:51:24.257893 2016] [:error] [pid 11280] groups = search.execute(ldap_user.connection)
[Wed Jan 13 16:51:24.257928 2016] [:error] [pid 11280] File "/usr/local/lib/python2.7/dist-packages/django_auth_ldap/config.py", line 150, in execute
[Wed Jan 13 16:51:24.257957 2016] [:error] [pid 11280] filterstr = self.filterstr % filterargs
[Wed Jan 13 16:51:24.257990 2016] [:error] [pid 11280] TypeError: format requires a mapping
The constructor of LDAPSearch
populates its attributes as follows: LDAPSearch
的构造LDAPSearch
填充其属性,如下所示:
self.base_dn = 'groupbase = ou=Groups,dc=mydomain'
self.scope = ldap.SCOPE_SUBTREE
self.filterstr = '(&(objectClass=posixGroup)(memberUid=%(user)s))'
/usr/local/lib/python2.7/dist-packages/django_auth_ldap/config.py #150 /usr/local/lib/python2.7/dist-packages/django_auth_ldap/config.py#150
def execute(self, connection, filterargs=()):
"""
Executes the search on the given connection (an LDAPObject). filterargs
is an object that will be used for expansion of the filter string.
The python-ldap library returns utf8-encoded strings. For the sake of
sanity, this method will decode all result strings and return them as
Unicode.
"""
try:
filterstr = self.filterstr % filterargs
results = connection.search_s(self.base_dn.encode('utf-8'),
self.scope,
filterstr.encode('utf-8'))
except ldap.LDAPError, e:
results = []
logger.error(u"search_s('%s', %d, '%s') raised %s" %
(self.base_dn, self.scope, filterstr, pprint.pformat(e)))
return self._process_results(results)
At last, I've found the solution: 最后,我找到了解决方案:
conf/local.cfg CONF / local.cfg
[ldap]
....
# Set up the basic group parameters.
groupbase = ou=Groups,dc=mydomain
groupfilter = (objectClass=posixGroup)
grouptype = PosixGroupType
...
The key factor is the use of the groupType PosixGroupType
, because the query on Groups would be filtered on the memberUid parameter by Django Auth LDAP (observe the else part of the user_groups
function: 关键因素是使用groupType
PosixGroupType
,因为对组的查询将由Django Auth LDAP在memberUid参数上进行过滤(请观察user_groups
函数的else部分:
class PosixGroupType(LDAPGroupType):
"""
An LDAPGroupType subclass that handles groups of class posixGroup.
"""
def user_groups(self, ldap_user, group_search):
"""
Searches for any group that is either the user's primary or contains the
user as a member.
"""
groups = []
try:
user_uid = ldap_user.attrs['uid'][0]
if 'gidNumber' in ldap_user.attrs:
user_gid = ldap_user.attrs['gidNumber'][0]
filterstr = u'(|(gidNumber=%s)(memberUid=%s))' % (
self.ldap.filter.escape_filter_chars(user_gid),
self.ldap.filter.escape_filter_chars(user_uid)
)
else:
filterstr = u'(memberUid=%s)' % (
self.ldap.filter.escape_filter_chars(user_uid),
)
search = group_search.search_with_additional_term_string(filterstr)
groups = search.execute(ldap_user.connection)
except (KeyError, IndexError):
pass
return groups
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.