ldap3 操作:搜索似乎失败(search_filter 语法与 RFC4515)
ldap3 operation: SEARCH seems to fail (search_filter syntax vs RFC4515)
编辑:tl;dr - SEARCH 中使用的 search_filter
参数可能不符合 RFC4515。
我在 Ubuntu 14.04 上有一个 Django 服务器 运行 版本 1.8.4。我正在使用 Python 3.4,为此我正在尝试使用 ldap3.
配置 LDAP 身份验证
这是分别从 1.6.2、12.04 和 2.7.3 升级到上述版本的一部分。一切正常,所以我认为问题出在我这边,而不是身份验证服务器。
它的工作方式是我有一个名为 authenticate_user.py 的文件,它接收通过 HTML 表单传递的用户名和密码,如下所示.
def authenticateStudent(request):
username = request.POST.get('username','')
logger.info("User " + username + " has logged in.")
password = request.POST.get('password','')
x = Auth(username, password)
retVal = x.AuthenticatePy()
logger.info('retVale is '+str(retVal)) #this returns False
#more code and more logging
该方法从 Auth class(如下所示)实例化一个对象,将用户名和密码存储在其中,然后在该 class.[=17= 中调用 AuthenticatePy() 方法]
import logging
import sys
import os.path,subprocess
import ldap3 as ldap
from ldap3 import Connection, Server, SIMPLE, SYNC, SUBTREE, ALL
logger = logging.getLogger('Submission')
class Auth():
studentName = ""
studentEmail = ""
studentMatrik = ""
def __init__(self, username, password):
self.username = username
self.password = password
def AuthenticatePy(self):
user_dn = "cn="+self.username+",ou=users,ou=data,ou=prod,ou=authserver,dc=domain,dc=tld"
base_dn = "dc=domain,dc=tld"
server = Server("authserver.domain.tld", port=636, use_ssl=True)
filter = "uid="+self.username #might be incorrect
try:
#if authentication successful, get the full user data
connect = Connection(server, user=user_dn, password=self.password)
connect.bind()
logger.info('Connection Bind Complete!') #the last logged message from this method
result = connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE)
logger.info('SEARCHING COMPLETE') #does not appear in the log
# return all user data results
connect.unbind()
uname = result[0][1]['cn'][0]
studentName = result[0][1]['fullName'][0]
studentEmail = result[0][1]['imHauptEMail'][0]
studentMatrik = result[0][1]['imMatrikelNr'][0]
logger.info('studentName is '+str(studentName))
if uname == self.username :
return studentName + '$' + studentEmail + '$' + studentMatrik
else:
return False
except ldap.LDAPExceptionError:
connect.unbind()
return False
我看到的最后一条日志消息是 'Connection Bind Complete!',我不太确定发生了什么问题。知道我做错了什么吗?
编辑:我对此进行了一段时间的故障排除,我开始认为问题可能出在我传递搜索功能的 search_filter
参数中。 ldap3 关于 SEARCH 操作的文档声明过滤器字符串应该符合 RFC4515,但我不确定我是否提供了这一点。
我是 ldap3 的作者。 ldap 过滤器必须包含在括号中。请尝试在过滤器中添加前后括号:
filter = "(uid="+self.username + ")"
再见,
乔瓦尼
我设法解决了这个问题。我对 search_filter
参数的语法确实是错误的。
需要按照另一个答案中的设置进行设置:
filter = "(uid="+self.username + ")"
但是,我还需要指出我想要哪些属性 return,因此 connect.search()
的参数需要更改:
connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE, attributes=['cn', 'fullName', 'imHauptEmail', 'imMatrikelNr'])
此外,访问 returned 属性的方式与在 Python 2.7 的 python-ldap
库中的方式不同,可以通过 connect.response
访问,这是一个字典列表。在取消绑定连接之前,您必须访问这些属性,因此 connect.unbind()
被移动到存储属性所需的值之后。
uname = str(connect.response[0]['attributes']['cn'][0])
studentName = str(connect.response[0]['attributes']['fullName'][0])
studentEmail = str(connect.response[0]['attributes']['imHauptEMail'][0])
studentMatrik = str(connect.response[0]['attributes']['imMatrikelNr'][0])
connect.unbind()
实际上所有这些都在 documentation 中进行了解释(请参阅底部的示例部分)。我只需要读几遍就可以了。
编辑:tl;dr - SEARCH 中使用的 search_filter
参数可能不符合 RFC4515。
我在 Ubuntu 14.04 上有一个 Django 服务器 运行 版本 1.8.4。我正在使用 Python 3.4,为此我正在尝试使用 ldap3.
配置 LDAP 身份验证这是分别从 1.6.2、12.04 和 2.7.3 升级到上述版本的一部分。一切正常,所以我认为问题出在我这边,而不是身份验证服务器。
它的工作方式是我有一个名为 authenticate_user.py 的文件,它接收通过 HTML 表单传递的用户名和密码,如下所示.
def authenticateStudent(request):
username = request.POST.get('username','')
logger.info("User " + username + " has logged in.")
password = request.POST.get('password','')
x = Auth(username, password)
retVal = x.AuthenticatePy()
logger.info('retVale is '+str(retVal)) #this returns False
#more code and more logging
该方法从 Auth class(如下所示)实例化一个对象,将用户名和密码存储在其中,然后在该 class.[=17= 中调用 AuthenticatePy() 方法]
import logging
import sys
import os.path,subprocess
import ldap3 as ldap
from ldap3 import Connection, Server, SIMPLE, SYNC, SUBTREE, ALL
logger = logging.getLogger('Submission')
class Auth():
studentName = ""
studentEmail = ""
studentMatrik = ""
def __init__(self, username, password):
self.username = username
self.password = password
def AuthenticatePy(self):
user_dn = "cn="+self.username+",ou=users,ou=data,ou=prod,ou=authserver,dc=domain,dc=tld"
base_dn = "dc=domain,dc=tld"
server = Server("authserver.domain.tld", port=636, use_ssl=True)
filter = "uid="+self.username #might be incorrect
try:
#if authentication successful, get the full user data
connect = Connection(server, user=user_dn, password=self.password)
connect.bind()
logger.info('Connection Bind Complete!') #the last logged message from this method
result = connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE)
logger.info('SEARCHING COMPLETE') #does not appear in the log
# return all user data results
connect.unbind()
uname = result[0][1]['cn'][0]
studentName = result[0][1]['fullName'][0]
studentEmail = result[0][1]['imHauptEMail'][0]
studentMatrik = result[0][1]['imMatrikelNr'][0]
logger.info('studentName is '+str(studentName))
if uname == self.username :
return studentName + '$' + studentEmail + '$' + studentMatrik
else:
return False
except ldap.LDAPExceptionError:
connect.unbind()
return False
我看到的最后一条日志消息是 'Connection Bind Complete!',我不太确定发生了什么问题。知道我做错了什么吗?
编辑:我对此进行了一段时间的故障排除,我开始认为问题可能出在我传递搜索功能的 search_filter
参数中。 ldap3 关于 SEARCH 操作的文档声明过滤器字符串应该符合 RFC4515,但我不确定我是否提供了这一点。
我是 ldap3 的作者。 ldap 过滤器必须包含在括号中。请尝试在过滤器中添加前后括号:
filter = "(uid="+self.username + ")"
再见, 乔瓦尼
我设法解决了这个问题。我对 search_filter
参数的语法确实是错误的。
需要按照另一个答案中的设置进行设置:
filter = "(uid="+self.username + ")"
但是,我还需要指出我想要哪些属性 return,因此 connect.search()
的参数需要更改:
connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE, attributes=['cn', 'fullName', 'imHauptEmail', 'imMatrikelNr'])
此外,访问 returned 属性的方式与在 Python 2.7 的 python-ldap
库中的方式不同,可以通过 connect.response
访问,这是一个字典列表。在取消绑定连接之前,您必须访问这些属性,因此 connect.unbind()
被移动到存储属性所需的值之后。
uname = str(connect.response[0]['attributes']['cn'][0])
studentName = str(connect.response[0]['attributes']['fullName'][0])
studentEmail = str(connect.response[0]['attributes']['imHauptEMail'][0])
studentMatrik = str(connect.response[0]['attributes']['imMatrikelNr'][0])
connect.unbind()
实际上所有这些都在 documentation 中进行了解释(请参阅底部的示例部分)。我只需要读几遍就可以了。