首页 > 编程语言 >使用python 接入LDAP验证系统实践记录

使用python 接入LDAP验证系统实践记录

时间:2022-10-29 15:34:18浏览次数:62  
标签:dn search uid python LDAP 接入 base ldap

LDAP简介

LDAP(Light Directory Access Portocol)是轻量目录访问协议,基于X.500标准,支持TCP/IP。

LDAP基本概念

LDAP的目的是为各种软件提供统一标准的认证机制,所有软件就可以不再用独有的用户管理方法,而是通过这种统一的认证机制进行用户认证。

LDAP基本结构

LDAP目录以树状的层次结构来存储数据。每个目录记录都有标识名(Distinguished Name,简称DN),用来读取单个记录,一般是这样的:
cn=username,ou=people,dc=test,dc=com
关键字的含义如下:
base dn:LDAP目录树的最顶部,也就是树的根,是上面的dc=test,dc=com部分,一般使用公司的域名,也可以写做o=test.com,前者更灵活一些。
dc:Domain Component,域名部分。
ou:Organization Unit,组织单位,用于将数据区分开。
cn:Common Name,一般使用用户名。
uid:用户id,与cn的作用类似。
sn:Surname, 姓。
rdn:Relative dn,dn中与目录树的结构无关的部分,通常存在cn或者uid这个属性里。
所以上面的dn代表一条记录,代表一位在test.com公司people部门的用户username。

flask项目对于LDAP有ldap3库

通过 ldap3 构造处理类 配置即可,配置一般向公司的运维人员要
代码如下:

class LDAPUtil(object):
    def __init__(self, ldap_host=None, port=None, base_dn=None, base_user=None, base_password=None):
        self.base_dn = base_dn
        try:
            server = Server(ldap_host, port, get_info=ALL)
            self.ldapconn = Connection(server, user=base_user, password=base_password, auto_bind=False)
            self.ldapconn.bind()
        except Exception as e:
            print(e)

    def ldap_search_dn(self, type_check="uid", value=None):
        obj = self.ldapconn
        search_base = self.base_dn
        search_scope = SUBTREE
        search_filter = f"({type_check}={value})"
        try:
            obj.search(search_base, search_filter, search_scope, attributes=['cn', 'uid', ])  # , paged_size=1
            if len(obj.response) == 1:
                return obj.response[0]['dn']
            else:
                return None
        except Exception as e:
            print(e)

    def authentication_by(self, type_check="uid", value=None, passwd=None):
        if not value or not passwd:
            return False
        obj = self.ldapconn
        bind_dn = self.ldap_search_dn(type_check=type_check, value=value)
        print(bind_dn)
        try:
            if obj.rebind(bind_dn, passwd):  # 可以使用搜索得到的绑定用户名uid,即可省去自己构造
                return True
            else:
                return False
        except Exception as e:
            print('e:' + str(e))
ldap = LDAPUtil(ldap_host, int(port), base_dn, base_user, base_password)
# 首先可以通过搜索获得正确格式的名称
search_ldap_by_uid = ldap.ldap_search_dn(type_check="uid", value="name")
search_ldap_by_mail = ldap.ldap_search_dn(type_check="mail", value="[email protected]")
search_ldap_by_cn = ldap.ldap_search_dn(type_check="cn", value="Name")
# 然后就可以传入不同类型的用户名进行验证了,如search_ldap_by_uid是查询得到的正确格式的用户id,search_ldap_by_mail是邮箱格式的用户名,search_ldap_by_cn是用户名
authentication_result = ldap.authentication_by(type_check=search_ldap_by_uid, value="name", passwd="password")  # BOOL 是否验证成功

另外,也可以通过flask_ldap3_login这个库进行配置即可使用,flask_ldap3_login对ldap3进行了封装,直接配置就可以使用,比较方便
代码如下:

from flask_ldap3_login import LDAP3LoginManager


ldap_manager = LDAP3LoginManager()
ldap_manager.init_config({"LDAP_HOST": LDAP_HOST,  # 形如'ldap://xxx.xxx.xxx.xxx:389'
                          "LDAP_BASE_DN": LDAP_BASE_DN,  # 形如'dc=test,dc=com'
                          "LDAP_USER_LOGIN_ATTR": LDAP_USER_LOGIN_ATTR,  # 'uid'  # 'cn' 'mail'
                          "LDAP_USER_SEARCH_SCOPE": LDAP_USER_SEARCH_SCOPE,  # 'SUBTREE'
                          "LDAP_BIND_USER_DN": LDAP_BIND_USER_DN,  # 形如'cn=admin,dc=test,dc=com'
                          "LDAP_BIND_USER_PASSWORD": LDAP_BIND_USER_PASSWORD,  # admin的密码
                          "LDAP_ALWAYS_SEARCH_BIND": LDAP_ALWAYS_SEARCH_BIND,  # 一般是True
                          "LDAP_GROUP_OBJECT_FILTER": LDAP_GROUP_OBJECT_FILTER,  # "(objectclass=posixGroup)" 或者 "(objectclass=groupOfNames)" 这里踩了坑,需要配置上
                          })
# 然后就可以直接调用ldap_manager进行验证了
authentication_result = ldap_manager.authenticate("uid", "password")  # authentication_result .status.value = 2 则表示验证成功

以上就是此次接入LDAP的记录。

标签:dn,search,uid,python,LDAP,接入,base,ldap
From: https://www.cnblogs.com/vanjoe/p/16838819.html

相关文章

  • 上手python之数据类型转换和标识符
    数据类型转换为什么要转换类型数据类型之间,在特定的场景下,是可以相互转换的,如字符串转数字、数字转字符串等那么,我们为什么要转换它们呢?数据类型转换,将会是我们以后经常使......
  • 上手python之变量和字符串
    什么是变量变量:在程序运行时,能储存计算结果或能表示值的抽象概念。简单的说,变量就是在程序运行时,记录数据用的变量的定义格式: 变量就像盒子可以存放内容 变量的特征  ......
  • 上手Python之函数进阶
    函数多返回值问:如果一个函数如些两个return(如下所示),程序如何执行答:只执行了第一个return,原因是因为return可以退出当前函数,导致return下方的代码不执行 多个返回值如......
  • python题目:计算今天是一年当中的第多少天【多测师_王sir】【杭州多测师】
    python题目:计算今天是一年当中的第多少天importdatetimey=int(input('请输入4位数字的年份:'))#获取年份m=int(input('请输入月份:'))#获取月份d=int(input......
  • python 的多行输入
    a,b=input().split("")#输入字符串(默认返回类型)a和b以(空格)分隔a,b,c=eval(input())#输入三个值(任何类型)中间由逗号分隔a,b,c=int(input())......
  • 基于python指定包的安装路径方法(linux)
    通常python安装包都会被默认装在/usr/local/pythonx/lib/site-packages(linux),但是我们有时想自定义包的安装路径,比如自己项目的某个路径,这样在部署的时候就不用再安装了,大......
  • 查看python中安装包的一些信息
    1.piplist  #列出当前环境中的所有安装包2. pipindexversionsxxx  #展示包的所有版本信息3. pipshowxxx  #展示包的当前版本的详细信息 4.pipin......
  • python自学 简单的网站开发 3
    创建子路由1.项目过大的时候,总路由不宜放过多的配置文件,可以把总路由的配置放置到子路由里面去。先在myapp中新增一个url.py的文件。 2.然后把总路由的内容放到u......
  • python的魔法
    python的魔法方法比较多。在此处,我将使用类编程的方式串联各种魔法方法的应用1.初始化创建类以及格式化输出__init__;__repr__;__str__; 解析:__init__这是一个函......
  • python 安装 jieba分词第三方库 报错 以及解决
      在安装jieba第三方库的时候,Python报错pip._vendor.urllib3.exceptions.ReadTimeoutError:HTTPSConnectionPool(host='files.pythonhosted.org',port=443):Readt......