需要提前安裝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)