根据Django中的登录用户名获取LDAP组(Get LDAP group based on login username in Django)

我需要使用Django中的LDAP查询来检索用户所在的组列表。 用例是:用户填写他的LDAP登录凭据,Django将对他进行身份验证,并且还将分配他的LDAP组

用户登录完美地工作,但我不能使用memberUid=%(user)s来过滤组。 我正在寻找正确的方法将用户名作为过滤参数传递给“groupfilter”属性 。 我用LDAP应用程序浏览器测试了这个查询,并且似乎正常工作。

操作系统: Ubuntu 14.04 x64 Python版本: 2.7.6 Django版本:1,6,11 ,'final',0)

RatticWeb LDAP配置

我使用RatticWeb django应用程序通过以下本地配置管理用户密码(另请参阅Rattic存储库wiki ):

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

编辑:错误的原因

LDAPSearch的构造函数按如下方式填充它的属性:

self.base_dn = 'groupbase = ou=Groups,dc=mydomain' self.scope = ldap.SCOPE_SUBTREE self.filterstr = '(&(objectClass=posixGroup)(memberUid=%(user)s))'

RatticWeb LDAP configuration

I'm using RatticWeb django application to manage users' passwords with the following local configuration (see also Rattic repository wiki):

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

EDIT: Cause of the error

The constructor of LDAPSearch populates its attributes as follows:

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

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)

最满意答案

最后,我找到了解决方案:

CONF / local.cfg

[ldap] .... # Set up the basic group parameters. groupbase = ou=Groups,dc=mydomain groupfilter = (objectClass=posixGroup) grouptype = PosixGroupType ...

关键因素是使用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

At last, I've found the solution:

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:

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

更多推荐