把自己使用到的ldap调用的代码分享出来,希望大家可以参考

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
@Time : 2019/11/14 5:37 PM
@Author : NoSong
@File : LdapBaseApi.py
@Software: PyCharm
# 接口文档: https://ldap3.readthedocs.io/
# https://ldap3.readthedocs.io/tutorial_operations.html#
""" ldap_config = {
'host': "192.168.13.133",
'port': 389,
'base_dn': 'dc=domain,dc=com',
'user': 'admin',
'password': 'admin',
} from ldap3 import Server, Connection, SUBTREE, ALL_ATTRIBUTES
from ldap3.core.exceptions import LDAPBindError
from ldap3 import MODIFY_REPLACE
from ldap3.utils.dn import safe_rdn
import sys
reload(sys)
sys.setdefaultencoding('utf8') class LDAP(object):
def __init__(self, host, port, user, password, base_dn):
dn = "cn=%s,%s" % (user, base_dn)
self.server = Server(host=host, port=port)
self.base_dn = base_dn
self.__conn = Connection(self.server, dn, password, auto_bind=True) def add_ou(self, ou, oid):
"""
参考: https://ldap3.readthedocs.io/tutorial_operations.html#create-an-entry
添加oy
:param ou: 'ou=测试部,dc=domain,dc=com' 或者 'ou=测试子部门,ou=测试部,dc=domain,dc=com'
:param oid: 部门id保存至st中
:return:
""" return self.__conn.add(ou, 'organizationalUnit', {"st": oid}) def add_user(self, userid, username, mobile, mail, title, ou_dn, gidnumber=501, alias=None):
"""
参考: https://ldap3.readthedocs.io/tutorial_operations.html#create-an-entry
:param userid: "linan"
:param username: "姓名" cn=姓名
:param mobile:
:param mail: "xxx@domain.com"
:param title:
:param ou_dn: "ou=运维中心,dc=domain,dc=com"
:param gidnumber: 501 默认用户组
:return:
"""
l = self.__conn
objectclass = ['top', 'person', 'inetOrgPerson', 'posixAccount']
add_dn = "cn=%s,%s" % (username, ou_dn) # 也可以随机生成,我先随便写一个值,这个需要自己定义规则
password = '%s@qwe' % userid
uidNumber = '%s' % userid.strip("xxx")
# 添加用户
s = l.add(add_dn, objectclass, {'mobile': mobile,
'sn': userid,
'mail': mail,
'userPassword': password,
'title': title,
'uid': username,
'gidNumber': gidnumber,
'uidNumber': uidNumber,
'homeDirectory': '/home/users/%s' % userid,
'loginShell': '/bin/bash'
})
return s def get_oudn_by_st(self, st, base_dn=None):
"""
根据 st值 获取组织dn
参考: https://ldap3.readthedocs.io/tutorial_searches.html
:param base_dn:
:param st: 部门id
:return: entry
"""
if not base_dn:
base_dn = self.base_dn
# 查询ou 中 返回的信息 attribute 包含 st
status = self.__conn.search(base_dn, '(objectclass=organizationalUnit)', attributes=["st"])
if status:
flag = False
for i in self.__conn.entries:
if st:
if st in i.entry_attributes_as_dict["st"]: return i
else:
return False
else:
return False def get_object_classes_info(self, objec_classes):
"""
获取 Ldap中 object_classes的必要参数以及其他信息
参考: https://ldap3.readthedocs.io/tutorial_searches.html
:param objec_classes: objec_classes
:return:
"""
print self.server.schema.object_classes[objec_classes] def get_userdn_by_mail(self, mail, base_dn=None):
"""
通过邮箱地址,获取用户dn。部分没有邮箱地址的用户被忽略,不能使用ldap认证
参考: https://ldap3.readthedocs.io/tutorial_searches.html
:param mail:
:param base_dn:
:return:
"""
if not base_dn:
base_dn = self.base_dn
status = self.__conn.search(base_dn,
search_filter='(mail={})'.format(mail),
search_scope=SUBTREE,
attributes=ALL_ATTRIBUTES,
)
if status:
flag = False
for i in self.__conn.entries:
# print(i.entry_dn)
return i
else:
return False
else:
return False def get_userdn_by_args(self, base_dn=None, **kwargs):
"""
参考: https://ldap3.readthedocs.io/tutorial_searches.html
获取用户dn, 通过 args
可以支持多个参数: get_userdn_by_args(mail="xxx@domain.com", uid="姓名")
会根据 kwargs 生成 search的内容,进行查询: 多个条件是 & and查询
返回第一个查询到的结果,
建议使用唯一标识符进行查询
这个函数基本可以获取所有类型的数据
:param base_dn:
:param kwargs:
:return:
"""
search = ""
for k, v in kwargs.items():
search += "(%s=%s)" % (k, v)
if not base_dn:
base_dn = self.base_dn
if search:
search_filter = '(&{})'.format(search)
else:
search_filter = ''
status = self.__conn.search(base_dn,
search_filter=search_filter,
search_scope=SUBTREE,
attributes=ALL_ATTRIBUTES
) if status:
return self.__conn.entries
else:
return False def authenticate_userdn_by_mail(self, mail, password):
"""
验证用户名密码
通过邮箱进行验证密码
:param mail:
:param password:
:return:
""" entry = self.get_userdn_by_mail(mail=mail) if entry:
bind_dn = entry.entry_dn
try:
Connection(self.server, bind_dn, password, auto_bind=True)
return True
except LDAPBindError:
return False else:
print("user: %s not exist! " % mail)
return False def update_user_info(self, user_dn, action=MODIFY_REPLACE, **kwargs):
""" :param dn: 用户dn 可以通过get_userdn_by_args,get_userdn_by_mail 获取
:param action: MODIFY_REPLACE 对字段原值进行替换 MODIFY_ADD 在指定字段上增加值 MODIFY_DELETE 对指定字段的值进行删除
:param kwargs: 要进行变更的信息内容 uid userPassword mail sn gidNumber uidNumber mobile title
:return:
"""
allow_key = "uid userPassword mail sn gidNumber uidNumber mobile title".split(" ")
update_args = {}
for k, v in kwargs.items():
if k not in allow_key:
msg = "字段: %s, 不允许进行修改, 不生效" % k
print(msg)
return False
update_args.update({k: [(action, [v])]})
print(update_args)
status = self.__conn.modify(user_dn, update_args)
return status def update_user_cn(self, user_dn, new_cn):
"""
修改cn dn: cn=用户,ou=运维部,ou=研发中心,dc=domain,dc=com
rdn就是 cn=用户
Example:
from ldap3.utils.dn import safe_rdn
safe_rdn('cn=b.smith,ou=moved,ou=ldap3-tutorial,dc=demo1,dc=freeipa,dc=org')
[cn=b.smith] :param dn:
:param new_cn:
:return:
"""
s = self.__conn.modify_dn(user_dn, 'cn=%s' % new_cn)
return s def update_ou(self, dn, new_ou_dn):
"""
更换所在的OU
:param dn: 要进行变动的DN
:param new_ou_dn: 新的OU DN
:return:
"""
rdn = safe_rdn(dn)
print(rdn)
s = self.__conn.modify_dn(dn, rdn[0], new_superior=new_ou_dn)
return s def delete_dn(self, dn):
"""
要进行删除的DN
:param dn:
:return:
"""
# 如果不是以cn开头的需要清理(删除) sub-link
if not dn.startswith("cn"):
# 获取dn 下所有 sub Person DN 进行删除
allUserEntry = self.get_userdn_by_args(base_dn=dn, objectClass="Person")
if allUserEntry:
for userentry in allUserEntry:
self.__conn.delete(userentry.entry_dn)
print("deleting ou %s and delete sub Person DN: %s" % (dn, userentry.entry_dn))
# 获取dn 下所有 sub OU进行删除
allOuEntry = self.get_userdn_by_args(base_dn=dn, objectClass="organizationalUnit")
if allOuEntry:
for ouEntry in reversed(allOuEntry):
s = self.__conn.delete(ouEntry.entry_dn)
print("deleting ou %s and delete sub organizationalUnit DN: %s" % (dn, ouEntry.entry_dn))
else:
s = self.__conn.delete(dn)
# print(self.__conn.result)
return s if __name__ == '__main__':
ldapObj = LDAP(**ldap_config)
# 同步企业微信 组织架构 to Ldap
# 同步企业微信 User To ldap
# -------------------------------
# 删除DN, 对DN下的 sub 进行递归删除
# s = ldapObj.get_oudn_by_st("1")
# status = ldapObj.delete_dn(s.entry_dn)
# print(status)
# -------------------------------
# 验证用户密码
# s = ldapObj.authenticate_userdn_by_mail("linan@domain.com", "xxx9999@qwe")
# - -----------------------------
# 添加用户
# s = ldapObj.add_user("xxx9999", "李南", "190283812", "linan@domain.com", "运维",
# ou_dn="ou=运维中心,dc=domain,dc=com")
# --------------------------------
# 查询 ou st 组id
# s = obj.get_oudn_by_st(st="1")
# --------------------------------
# 添加OU
# obj.add_ou("ou=总部,dc=domain,dc=com", 1)
# obj.add_ou("ou=研发中心,ou=总部,dc=domain,dc=com", 2)
# --------------------------------
# 查询用户是否存在 - 通过 mail 获取用户 dn_entry
# ldapObj.get_userdn_by_mail(mail="linan@domain.com")
# --------------------------------
# 根据 参数 查询用户DN data = [dn_entry, ...] ,多个参数为 &
# data = ldapObj.get_userdn_by_args(cn="李南",mail="xxxx")
# --------------------------------
# 对指定dn 进行参数修改 多个参数可以一起修改
# s = ldapObj.update_user_info(data[0].entry_dn, userPassword="123456")
# --------------------------------
# 对指定DN 变更 OU-DN
# s = ldapObj.update_user_ou(data[0].entry_dn, s.entry_dn)
# --------------------------------
# 对指定DN 修改CN名称
# ldapObj.update_cn(data[0].entry_dn,new_cn="李南男")
# --------------------------------
# 获取objectClass 详细信息
# ldapObj.get_object_classes_info("organizationalUnit")
# ldapObj.get_object_classes_info("posixAccount")
# ldapObj.get_object_classes_info("inetOrgPerson")
# ldapObj.get_object_classes_info("person")
# 没有邮箱地址的用户: s = ldapObj.get_userdn_by_args(ou="研发中心")
data= ldapObj.get_userdn_by_args(base_dn=s[0].entry_dn, objectclass = "organizationalUnit")
for i in data:
print(i.entry_dn)
# print(s)

python使用ldap3进行接口调用的更多相关文章

  1. 什么是 WSGI -- Python 中的 “CGI” 接口简介

    今天在 git.oschina 的首页上看到他们推出演示平台,其中,Python 的演示平台支持 WSGI 接口的应用.虽然,这个演示平台连它自己提供的示例都跑不起来,但是,它还是成功的勾起了我对 W ...

  2. python面向对象进阶 反射 单例模式 以及python实现类似java接口功能

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...

  3. 戏说WSGI(Python Web服务网关接口)--[转载]

    戏说WSGI(Python Web服务网关接口) 当你在Python的世界中冒险,突然遭遇一只Web怪兽,你会选择什么武器对付它?在兵器谱上,下列兵器可谓名列前茅: Zope,厚重的长枪.较早出现的武 ...

  4. Python语言学习之C++调用python

    C++调用python 在C/C++中嵌入Python,可以使用Python提供的强大功能,通过嵌入Python可以替代动态链接库形式的接口,这样可以方便地根据需要修改脚本代码,而不用重新编译链接二进 ...

  5. Python实例浅谈之三Python与C/C++相互调用

    一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...

  6. 2015/10/9 Python基础(21):可调用和可执行对象

    在Python中有多种运行外部程序的方法,比如,运行操作系统命令或另外的Python脚本,或执行一个磁盘上的文件,或通过网络来运行文件.这完全取决于想要干什么.特定的环境包括: 在当前脚本继续运行 创 ...

  7. WSGI——python web 服务器网关接口

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html 一:服务器.服务器软件.应用程序(后台) 我们常说“服务器”,实际上服务器是一个很宽 ...

  8. Python与C/C++相互调用(python2 调c++那个试了ok)

    一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...

  9. Python与C/C++相互调用(转)

    原文链接 作者 一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库 ...

随机推荐

  1. 数据仓库模型ETL架构(DWI/DWR/DM)

    1.DWI DWI:数据湖.数据砥柱,一般存放在HDFS 数据仓库的基础数据来源,各种杂七杂八的数据 关键点:数据清洗.数据整合.异常处理.增量获取 ETL:E-数据抽取.数据清洁.格式转换,T-生成 ...

  2. 雪妖现世:给SAP Fiori Launchpad增添雪花纷飞的效果

    1995年7月,台湾大宇公司发布了一款国产单机角色扮演游戏神作:<仙剑奇侠传1>,所谓"一包烟,一杯茶",就能在电脑面前坐一整天. 这么经典的游戏Jerry当然已经通关 ...

  3. 使用虹软ArcFac,java 离线SDK 进行人脸识别

    公司项目需要人脸识别登录,需要支持离线识别,所以无法使用在线的人脸识别的API,于是使用到了离线SDK来对比识别人脸相识度. 获取人脸抓拍的图片需要对接设备,这里不做记录,假设我们已经获取到了人脸图片 ...

  4. 你真的会使用 VMware Workstation 吗

    你真的会使用VMware Workstation吗?网上有很多教程,虽然都还可以,但总感觉差强人意.所以笔者在这里分享自己的使用心得,让大家参考一下,个人认为是最好的了. 简介 VMware Work ...

  5. SQL与NoSQL区别--商业SQL数据库衰落--oracle面临困境

    转自:商用数据库之死:Oracle 面临困境 这二十年来,商业数据库市场仍然是 IT 行业最稳定.最具黏性的领域之一,Oracle.IBM 和微软三家厂商瓜分了 80% 的份额.然而,我们认为这个领域 ...

  6. VS Code好用到飞起的配置设置

    Visual Studio Code是一个轻量级但功能强大的源代码编辑器,可在桌面上运行,适用于Windows,macOS和Linux.它内置了对JavaScript,TypeScript和Node. ...

  7. 分布式存储-ceph

    1. ceph 简介 Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统().ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司 ...

  8. Kotlin调用Java程序重点分析

    在上一次https://www.cnblogs.com/webor2006/p/11530801.html中学习了Kotlin调用Java的使用方式及一些注意点,这次继续其这个场景进一步学习. 数组( ...

  9. 编程小白入门分享一:git的最基本使用

    git简介 引用了网上的一张图,这张图清晰表达git的架构.workspace是工作区,可以用编辑器直接编辑其中的文件:Index/Stage是暂存区,编辑后的文件可以添加到(add)暂存区:Repo ...

  10. 第六周测试补交 多线程代码和sumN

    1.多线程代码 要求:编译运行多线程程序,提交编译和运行命令截图 2.sumN 要求:1-N求和的截图