定义一个类,用于初始化ldap连接,验证、查找用户等功能

# -*- coding: UTF-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8') import ldap,logging,time
logfile = 'e:\\a.txt'
# logging.basicConfig(filename=logfile,level=logging.INFO)
# logging.basicConfig(format='%(time.asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.basicConfig(level=logging.INFO,
#format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', #返回值:Thu, 26 May 2016 15:09:31 t11.py[line:92] INFO
format='%(asctime)s %(levelname)s %(message)s',
#datefmt='%a, %d %b %Y %H:%M:%S',
#datefmt='%Y/%m/%d %I:%M:%S %p', #返回2016/05/26 03:12:56 PM
datefmt='%Y-%m-%d %H:%M:%S', #返回2016/05/26 03:12:56 PM
filename=logfile#,
#filemode='a' #默认为a
)
#logging输出结果:
#2016-05-26 15:22:29 INFO liu1 valid passed.
#2016-05-26 15:22:37 INFO liu1 valid passed. class ldapc:
def __init__(self,ldap_path,baseDN,domainname,ldap_authuser,ldap_authpass):
self.baseDN = baseDN
self.ldap_error = None
ldap_authduser = '%s\%s' %(domainname,ldap_authuser)
self.l=ldap.initialize(ldap_path)
self.l.protocol_version = ldap.VERSION3
try:
self.l.simple_bind_s(ldap_authduser,ldap_authpass)
except ldap.LDAPError,err:
self.ldap_error = 'Connect to %s failed, Error:%s.' %(ldap_path,err.message['desc'])
print self.ldap_error
# finally:
# self.l.unbind_s()
# del self.l def search_users(self,username): #模糊查找,返回一个list,使用search_s()
if self.ldap_error is None:
try:
searchScope = ldap.SCOPE_SUBTREE
searchFiltername = "sAMAccountName" #通过samaccountname查找用户
retrieveAttributes = None
searchFilter = '(' + searchFiltername + "=" + username +'*)'
ldap_result =self.l.search_s(self.baseDN, searchScope, searchFilter, retrieveAttributes)
if len(ldap_result) == 0: #ldap_result is a list.
return "%s doesn't exist." %username
else:
# result_type, result_data = self.l.result(ldap_result, 0)
# return result_type, ldap_result
return ldap_result
except ldap.LDAPError,err:
return err def search_user(self,username): #精确查找,返回值为list,使用search()
if self.ldap_error is None:
try:
searchScope = ldap.SCOPE_SUBTREE
searchFiltername = "sAMAccountName" #通过samaccountname查找用户
retrieveAttributes = None
searchFilter = '(' + searchFiltername + "=" + username +')'
ldap_result_id =self.l.search(self.baseDN, searchScope, searchFilter, retrieveAttributes)
result_type, result_data = self.l.result(ldap_result_id, 0)
if result_type == ldap.RES_SEARCH_ENTRY:
return result_data
else:
return "%s doesn't exist." %username
except ldap.LDAPError,err:
return err def search_userDN(self,username): #精确查找,最后返回该用户的DN值
if self.ldap_error is None:
try:
searchScope = ldap.SCOPE_SUBTREE
searchFiltername = "sAMAccountName" #通过samaccountname查找用户
retrieveAttributes = None
searchFilter = '(' + searchFiltername + "=" + username +')'
ldap_result_id =self.l.search(self.baseDN, searchScope, searchFilter, retrieveAttributes)
result_type, result_data = self.l.result(ldap_result_id, 0)
if result_type == ldap.RES_SEARCH_ENTRY:
return result_data[0][0] #list第一个值为用户的DN,第二个值是一个dict,包含了用户属性信息
else:
return "%s doesn't exist." %username
except ldap.LDAPError,err:
return err def valid_user(self,username,userpassword): #验证用户密码是否正确
if self.ldap_error is None:
target_user = self.search_userDN(username) #使用前面定义的search_userDN函数获取用户的DN
if target_user.find("doesn't exist") == -1:
try:
self.l.simple_bind_s(target_user,userpassword)
logging.info('%s valid passed.\r'%(username)) #logging会自动在每行log后面添加"\000"换行,windows下未自动换行
return True
except ldap.LDAPError,err:
return err
else:
return target_user def update_pass(self,username,oldpassword,newpassword): #####未测试#########
if self.ldap_error is None:
target_user = self.search_userDN(username)
if target_user.find("doesn't exist") == -1:
try:
self.l.simple_bind_s(target_user,oldpassword)
self.l.passwd_s(target_user,oldpassword,newpassword)
return 'Change password success.'
except ldap.LDAPError,err:
return err
else:
return target_user ldap_authuser='liu1'
ldap_authpass='pass'
domainname='uu'
ldappath='ldap://192.168.200.25:389' baseDN='OU=优优,DC=uu,DC=yuu,DC=com' #ldap_authuser在连接到LDAP的时候不会用到baseDN,在验证其他用户的时候才需要使用
username = 'liu1' #要查找/验证的用户
p=ldapc(ldappath,baseDN,domainname,ldap_authuser,ldap_authpass)
print p.valid_user('Lily','lpass') #调用valid_user()方法验证用户是否为合法用户

遍历OU下的用户函数:

def search_OU(self): #精确查找,最后返回该用户的DN值
if self.ldap_error is None:
try:
searchScope = ldap.SCOPE_SUBTREE
#searchFiltername = "sAMAccountName" #通过samaccountname查找用户
retrieveAttributes = None
searchFilter = '(&(objectClass=person))'
ldap_result =self.l.search_s(self.baseDN, searchScope, searchFilter, retrieveAttributes)
if ldap_result is not None:
udict = {}
usersinfor = []
for pinfor in ldap_result:
#pinfor是一个tuple,第一个元素是该用户的CN,第二个元素是一个dict,包含有用户的所有属性
if pinfor[1]:
p=pinfor[1]
sAMAccountName = p['sAMAccountName'][0] #返回值是一个list
displayName = p['displayName'][0]
#如果用户的某个属性为空,则dict中不会包含有相应的key
if 'department' in p:
department = p['department'][0]
else:
department = None
#print sAMAccountName,displayName,department
udict['sAMAccountName'] = sAMAccountName
udict['displayName'] = displayName
udict['department'] = department
usersinfor.append(udict)
# print udict
return usersinfor
except ldap.LDAPError,err:
return err
finally:
self.l.unbind_s()
del self.l

baseDN='OU=Admin,DC=u,DC=y,DC=com' #需要遍历的OU
p=ldapc(ldappath,baseDN,domainname,ldap_authuser,ldap_authpass)
users = p.search_OU()
print users[0]['department']

#retrieveAttributes = None
searchFilter = '(&(objectClass=person))'
attrs = ['cn','uid','mail']
ldap_result =self.l.search_s(self.baseDN, searchScope, searchFilter, attrs) #只过滤attrs属性,如果为*,则过滤所有属性

分页返回LDAP查询结果:

import ldap
from ldap.controls import SimplePagedResultsControl l = ldap.initialize('ldap://1.1.1.16')
l.simple_bind_s('user', 'Password')
baseDN=unicode('OU=集团,DC=uxin,DC=youxinpai,DC=com','utf8')
PAGE_SIZE = 500 #设置每页返回的条数
ATTRLIST = ['sAMAccountName','name', 'mail','department','title'] #设置返回的属性值
# ATTRLIST = None #设置为None则返回用户的所有属性
searchFilter = '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' #查询Enabled的用户
pg_ctrl = SimplePagedResultsControl(True, size=PAGE_SIZE, cookie="")
userdata = [] while True:
msgid = l.search_ext(baseDN,ldap.SCOPE_SUBTREE, searchFilter, ATTRLIST, serverctrls=[pg_ctrl])
_a, res_data, _b, srv_ctrls = l.result3(msgid)
# print 'res_data', len(res_data) ,msgid
userdata.extend(res_data)
cookie = srv_ctrls[0].cookie
if cookie:
pg_ctrl.cookie = cookie
else:
break print 'totalnum:', len(userdata)
print userdata[0]

ObjectClass类型如下:详细参考:http://www.cnblogs.com/dreamer-fish/p/5832735.html(LDAP查询过滤语法)http://www.morgantechspace.com/2013/05/ldap-search-filter-examples.html

objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson

Python通过LDAP验证、查找用户(class,logging)的更多相关文章

  1. Python使用LDAP做用户认证

    LDAP(Light Directory Access Portocol)是轻量目录访问协议,基于X.500标准,支持TCP/IP. LDAP目录以树状的层次结构来存储数据.每个目录记录都有标识名(D ...

  2. django使用LDAP验证

    1.安装Python-LDAP(python_ldap-2.4.25-cp27-none-win_amd64.whl)pip install python_ldap-2.4.25-cp27-none- ...

  3. 如何使用Python连接ldap

    如何使用Python连接ldap 好多使用ldap认证的软件都是Python的,比如superset和airflow, 好吧,他们都是airbnb家的.在配置ldap的时候可能会出现认证失败,你不知道 ...

  4. python实现ldap接入

    需要提前安装python-ldap模块 python接入ldap其实分了几个步骤: 1.使用一个管理员账户登陆到ldap 2.使用一个字段值是唯一的字段,去搜索到要验证用户的DN值(ldap搜索到的单 ...

  5. 通过ldap验证svn服务

    1.简单介绍: 这里需要介绍一点的就是svn服务器的验证是需要通过SASL机制的,那么SASL全称为(Simple Authentication and security Layer),是一种用来扩充 ...

  6. python入门学习:6.用户输入和while循环

    python入门学习:6.用户输入和while循环 关键点:输入.while循环 6.1 函数input()工作原理6.2 while循环简介6.3 使用while循环处理字典和列表 6.1 函数in ...

  7. Mybatis(二)入门程序-通过id查找用户、模糊查找用户、添加用户、删除用户

    根据下图myBatis的架构,创建一个使用MyBatis的工程.       一.配置MyBatis 环境(如图) 1.sqlMapConfig.xml 首先,导入jar包(上图右边)并加载路径,然后 ...

  8. 错误提示:通过 Web 服务器的身份验证的用户无权打开文件系统上的文件

    //win7中iis配置好了可是网页打不开,为什么.? //错误提示:通过 Web 服务器的身份验证的用户无权打开文件系统上的文件 //解决办法1.右键单击你的网站根目录文件夹,如wwwroot文件夹 ...

  9. 通过LDAP验证Active Directory服务

    原文地址:http://www.byywee.com/page/M0/S215/215725.html C#: using System; using System.Collections.Gener ...

随机推荐

  1. JVM几种垃圾回收器介绍

    整理自:http://www.cnblogs.com/lspz/p/6397649.html 一.如何回收? 1.1 垃圾收集算法: (1)标记-清除(Mark-Sweep)算法 这是最基础的算法,就 ...

  2. C++类型转化小结

    之前面试就有被问过关于使用类型转换的问题,因为主要是做Windows驱动的开发,一直都是纯C语言+汇编,当时真的是只用过C语言的强制类型转换,C语言的强制类型转换(Type Cast)很简单,不管什么 ...

  3. 【IT笔试面试题整理】数组中出现次数超过一半的数字

    [试题描述]数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. [试题分析]时间复杂度O(n),空间复杂度O(1) 思路1: 创建一个hash_map,key为数组中的数,value为此数 ...

  4. 基于Ip的刷投票排名及刷百度推广的自动化实现

    所有基于Ip的刷投票排名,只要不涉及用户登录情况,都可以在手机端自动化实现,因为电信运营商的ip地址段是无限的,理论上,飞行模式开关一次,所分配ip地址是变化的,这就有了大量的ip可用 在手机端写个a ...

  5. SOA和微服务架构的区别?

    转自知乎:https://www.zhihu.com/question/37808426/answer/93335393 SOA和微服务架构的区别? 微服务架构强调的第一个重点就是业务系统需要彻底的组 ...

  6. Spring 通过Java代码装配bean

    1. 背景 书接上文Spring自动化装配bean 尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化扫描配置是更为推荐的方式,但在有些情况下自动化扫描的方案行不通,如想要将第三方库中的组 ...

  7. 获取呈现在格表(table)记录的主键

    用mouse点击表格(table)的行或是批定列,获取记录的主键值.在ASP.NET的MVC应用程序中,已经没有办法象ASP.NET的Data控件一样,如GridView,DataList和Repea ...

  8. echart 数据视图 样式重写

    来源http://blog.csdn.net/u010705091/article/details/75212724 echarts折线图的数据视图样式重写 在echarts.js中,点击折线图的数据 ...

  9. 你得学会并且学得会的Socket编程基础知识

    这一篇文章,我将图文并茂地介绍Socket编程的基础知识,我相信,如果你按照步骤做完实验,一定可以对Socket编程有更好地理解. 本文源代码,可以通过这里下载 http://files.cnblog ...

  10. [javascript] 看知乎学习js闭包

    知乎:到底什么是闭包? 寸志: JavaScript 闭包的本质源自两点,词法作用域和函数当作值传递. 词法作用域,就是,按照代码书写时的样子,内部函数可以访问函数外面的变量.引擎通过数据结构和算法表 ...