python实现ldap接入
需要提前安装python-ldap模块
python接入ldap其实分了几个步骤:
1、使用一个管理员账户登陆到ldap
2、使用一个字段值是唯一的字段,去搜索到要验证用户的DN值(ldap搜索到的单个用户信息是一个元祖数据,DN值就是元祖数据的第一位数据,"cn=x,ou=xx,ou=xxx,ou=xxxx,dc=xxxxx,dc=com"这个就是DN值)
3、然后使用搜索到的用户的DN值和用户的密码再去登陆一把ldap
Backend.py
import ldap class LDAPBackend: def authenticate(self, username=None, password=None, **kwargs): AUTH_LDAP_SERVER_URI = "ldap://0.0.0.0:389" AUTH_LDAP_BIND_DN = 'cn=管理员账号,dc=域名,dc=com' AUTH_LDAP_BIND_PASSWORD = '管理员密码' AUTH_LDAP_BASE_DN = 'dc=域名,dc=com' if username and password: # 初始化ldap连接 ldapconn = ldap.initialize(AUTH_LDAP_SERVER_URI) # 设置连接协议为version3 ldapconn.protocol_version = ldap.VERSION3 # 使用管理员账号,密码登陆ldap ldapconn.simple_bind_s(AUTH_LDAP_BIND_DN, AUTH_LDAP_BIND_PASSWORD) # 根据我们需要的字段(此处的字段是值ldap查询到的数据的字段)搜索到指定的账户,sn是我用的,不同公司的可能不一样,需要根据自己的实际情况确定 ldap_result_id = ldapconn.search(AUTH_LDAP_BASE_DN, ldap.SCOPE_SUBTREE, "(sn={})".format(username), None) # 获取到查询的结果数据 result_type, result_data = ldapconn.result(ldap_result_id,1) # 如果查询到了用户就继续验证 if(not len(result_data) == 0): try: # 初始化ldap连接 ldapconn = ldap.initialize(AUTH_LDAP_SERVER_URI) # 使用刚刚查到的登陆用的DN信息和密码再次登陆一下ldap # 1、如果登陆成功会返回一个类似于右边的一个元祖数据(97, [], 1, []) # 2、如果登陆失败就会抛出一个ldap.INVALID_CREDENTIALS的异常 ldapconn.simple_bind_s(result_data[0][0], password) logger.debug("ldap auth success") return self._get_or_create_user(result_data[0]) except ldap.INVALID_CREDENTIALS: return None return None else: return None def _get_or_create_user(self, user_info=()): # 此处去应用的数据库查询用户的权限等信息,如果数据库没有这个用户,需要将用户信息持久化到数据库中去 # # # # return user
引用
user = LDAPBackend().authenticate(username=username, password=password)
遍历某个OU下的所有用户数据
AUTH_LDAP_SERVER_URI = "ldap://ip:port" # 服务器地址 AUTH_LDAP_BIND_DN = 'cn=Manager,dc=xxx,dc=com' AUTH_LDAP_BIND_PASSWORD = 'password' AUTH_LDAP_BASE_DN_LIST = ['ou1', 'ou2'] def authenticate(): ldapconn = ldap.initialize(AUTH_LDAP_SERVER_URI) ldapconn.protocol_version = ldap.VERSION3 ldapconn.bind_s(AUTH_LDAP_BIND_DN, AUTH_LDAP_BIND_PASSWORD) searchScope = ldap.SCOPE_SUBTREE retrieveAttributes = None searchFilter = "(&(objectClass=person))" # 这个参数的值是固定的person for AUTH_LDAP_BASE_DN in AUTH_LDAP_BASE_DN_LIST: ldap_result_id =ldapconn.search_s("ou={},ou=xx,dc=xxx,dc=com".format(AUTH_LDAP_BASE_DN), searchScope, searchFilter, retrieveAttributes) for res in ldap_result_id: print(res)