Ldap探索之路之directory-server(ApacheDs二次开发)
前沿
领导:Hi 小王,以前有没有接触过Ldap??
小王:啥?Ldap是啥?没接触过。
领导:那有没有使用过微软的AD?
小王;啥是AD?没有
领导:好吧,我简单说下,我们目前使用AD保存用户的信息,但是AD不是开源的,无法二次开发,使用起来不太方便,所以我们如果能找到一个同样支持Ldap协议的开源软件,那么就能通过对该开源软件进行二次开发,来满足我们的需要。具体让龙哥和你详细聊聊。
龙哥:巴拉巴拉
小王:太多新名词,没太明白,我先自己查查资料,了解下这些新的名词。
龙哥:好,有问题随时沟通。
正文
为了找到一个基于Ldap开源软件,而且还是熟悉的开发语言,进行二次开发,大体思考了下调研思路,先按照以下几个步骤:
1、Ldap协议是啥?
2、目前行业支持Ldap协议的产品有哪些?
3、这些软件是否有满足我们要求的?选择一个合适的软件。
4、下载开源项目及浏览其目录结构,了解子项目的大体功能。
5、找到启动类进行启动。
6、使用客户端登陆认证,根据用户名登陆是否能找到登陆入口?
7、阅读入口源码,并且以此为入口,找到增删改查的相关接口?
8、将登陆实现替换成目前使用的AD验证,也就是说,将内部的登陆验证,透传到正在使用的AD上,我们的开源项目只做入口、参数透传,不做正真验证。
9、部署到测试环境上。
10、暴露IP + 端口,进行验证。
思路明确后,我们只需要按照这个步骤进行调研,在该过程中,如果出现问题,随时做调整
Ldap协议介绍
它是基于X.500标准扽轻量级目录访问协议,是开发的Internet标准,支持跨平台的internet协议。
目录是一个为查询、浏览、搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。
目录数据库和关系型数据库不同,它有优异的读性能,但写性能差,并且没有事务处理,不适合存储修改频繁的数据。所以目录天生是用来查询的。
上述这段定义是摘抄自别的博客,很好的阐述了Ldap协议的特点,Ldap只是定义了协议,没有具体的实现,所有对其实现的产品都是支持Ldap协议的。
其他产品对其支持:
YAPI对其进行支持,通过配置Ldap的服务,能够通过Ldap进行登陆;
metabase对其进行支持,通过管理员配置Ldap参数,也能够通过Ldap进行登陆;
还有好多产品,我们这里就不一一列举了。
目前Ldap主要产品
SUNONE Directory Server、IBM Directory Server 、Novell Directory Server、Microsoft Active Directory上述3种产品都是不开源的,我们不能用,下面几个产品是开源的:Open Ldap:速度很快,但非主流应用、ApacheDs、OpenDJ、红帽目录服务器。
Ldap一些特征例如目录树概念、DC、OU、CN、SN、信息模型、命名模型、功能模型、安全模型等,大家上网搜搜,有很多文章在讲述,这里就不再阐述了。
选择一个开源软件:
选择的是ApacheDs,但是ApacheDs后端似乎存在损坏数据的问题,但是我们不会有这个问题,因为我们不用ApacheDs存储数据,只是作为一个入口及参数透传而已。
浏览开源项目目录结构,了解子项目的大体功能
下载源码包:
GitHub - apache/directory-server: Apache Directory Server
打开后发现一堆的子项目,看着头晕,但是我们只要弄明白2件事,入口类以及启动类,下面是打开后的目录结构:
从截图上可以看到,他的子项目还是比较多的
找到启动类进行启动
我们在标号为35的子项目中找到一个类:org.apache.directory.server.UberjarMain#main
从代码里看,貌似这个就是启动类,而且从pom文件里也能看出来应该是这个类
<mainClass>org.apache.directory.server.UberjarMain</mainClass>
那就试试呗,启动后发现报以下异常
Instance directory argument is missing
异常,看代码73行发现,他会获取一个目录,将该目录作为Ldap运行的时候存放一些文件的根目录,例如日志的输出、conf、partitions等,找到问题所在后,我们再启动的时候,在VM options配置instance.base.dir路径即可,配置完再次重启,发现正常启动,打印如下日志:
是否说明绑定的端口就是10389呢,我们通过ApacheDirectoryStudio客户端链接工具来验证,Hostname肯定是本地IP呗,验证成功,说明没问题,但是从截图中看到还有一个端口号10636,这个端口是干嘛的?
验证同样没问题,这2个端口有啥区别吗,既然这2个端口都生效,我们先猜猜,认证方式不可能是相同的,开源框架不会做这么无聊的事,是不是一个需要sasl认证,一个普通认证了,秉着一切问题都出至源码的理念,终于从server.xml中找到这2个ip的配置:
<ldapService id="ldapsService"enabled="true"enableLdaps="true"><tcpTransport><tcpTransport port="10636"/></tcpTransport><directoryService>#directoryService</directoryService>
</ldapService><ldapService id="ldapService"allowAnonymousAccess="false"saslHost="ldap.example.com"saslPrincipal="ldap/ldap.example.com@EXAMPLE.COM"searchBaseDn="ou=users,ou=system"maxTimeLimit="15000"maxSizeLimit="1000"><tcpTransport><tcpTransport port="10389" nbThreads="8" backLog="50"/></tcpTransport>
果然与我们开始猜想的一样。
使用客户端进行登陆,根据用户名登陆是否找到登陆入口
输入错误的用户名和秘密,查看日志,根据调用链是否能够找到入口?
从上图标注的序号可以看出,入口是标记为1的序号,通过一路跟踪代码发现,org.apache.directory.server.ldap.handlers.LdapRequestHandler#handle存在这个抽象方法,该抽象方法有10个实现类,包括绑定(登陆验证)、解绑、添加、修改、搜索、比较、删除、扩展等,我们从标号4也能看出来,登陆的时候调用的是BindRequestHandler,从而验证了我们的猜想。
阅读入口源码,并且以此我入口,找到增删改查的相关接口
这里就比较简单了,通过debug模式,可以查看到入参和调用轨迹
登陆校验接口
入参:
MessageType : BIND_REQUESTMessage ID : 1BindRequestVersion : '3'Name : 'uid=admin,ou=system'Simple authentication : '(omitted-for-safety)'
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived -》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》
org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessage
org.apache.directory.server.ldap.handlers.request.BindRequestHandler.handle -》
org.apache.directory.server.ldap.handlers.request.BindRequestHandler#handleSimpleAuth
搜索:
入参:
MessageType : SEARCH_REQUEST
Message ID : 22SearchRequestbaseDn : 'ou=schema'filter : '(objectClass=*)'scope : single leveltypesOnly : falseSize Limit : 1000Time Limit : no limitDeref Aliases : deref Alwaysattributes : 'hasSubordinates', 'objectClass'
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived-》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessageorg.apache.directory.server.ldap.handlers.request.AddRequestHandler#handle
添加用户:
入参:
MessageType : ADD_REQUEST
Message ID : 39Add Request :
Entrydn: cn=李四+uid=si.li+description=李四+sn=李+givenName=四+displayName=李四+mail=lisi@163.com+userPassword=123123,ou=laoniantuan,dc=example,dc=comobjectClass: inetOrgPersonobjectClass: organizationalPersonobjectClass: personobjectClass: topuid: si.limail: lisi@163.comgivenName: 四displayName: 李四description: 李四cn: 李四sn: 李
userPassword: 0x31 0x32 0x33 0x31 0x32 0x33
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived-》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessageorg.apache.directory.server.ldap.handlers.request.AddRequestHandler#handle
删除节点:
入参:
MessageType : DEL_REQUEST
Message ID : 54Del requestEntry : 'ou=laoniantuan,dc=example,dc=com'
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived-》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessageorg.apache.directory.server.ldap.handlers.request.DeleteRequestHandler#handle
修改节点:
入参:
MessageType : MODIFYDN_REQUEST
Message ID : 13ModifyDN ResponseEntry : 'ou=laoniantuan,dc=example,dc=com'New Rdn : 'ou=laorentuan'Delete old Rdn : trueNew superior : 'dc=example,dc=com'
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived
-》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》
org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessage
org.apache.directory.server.ldap.handlers.request.ModifyRequestHandler#handle
移动节点:
入参:
MessageType : MODIFYDN_REQUEST
Message ID : 24ModifyDN ResponseEntry : 'cn=李四+description=李四+displayName=李四+givenName=四+mail=lisi@163.com+sn=李+uid=si.li,ou=qingniantuan,dc=example,dc=com'New Rdn : 'cn=李四+description=李四+displayName=李四+givenName=四+mail=lisi@163.com+sn=李+uid=si.li'Delete old Rdn : trueNew superior : 'ou=laoniantuan,dc=example,dc=com'
调用轨迹:
org.apache.directory.server.ldap.LdapProtocolHandler.messageReceived
-》org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived -》
org.apache.directory.server.ldap.handlers.LdapRequestHandler.handleMessage
org.apache.directory.server.ldap.handlers.request.ModifyDnRequestHandler#handle
将ApacheDs校验登陆的部分透传到AD服务器,根据代码调用轨迹,只需要在org.apache.directory.server.ldap.handlers.request.BindRequestHandler#handleSimpleAuth类中调用AD服务器的链接验证即可,核心代码如下:
public static int checkUser(String username, String password) {if (StringUtils.isAnyEmpty(username, password)) {return Constants.CHECK_STATUS_PARAM_EMPTY;}String property = System.getProperty("ldap.server.url");Properties properties = System.getProperties();System.out.println(properties);Hashtable<String, String> env = new Hashtable<>();DirContext ctx = null;env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");env.put(Context.PROVIDER_URL, CON_URL);env.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION_SIMPLE);env.put(TIMEOUT, TIMEOUT_VALUE);// 连接超时设置为2秒//env.put(Context.SECURITY_PRINCIPAL, EMAIL_SUBFIX + username);env.put(Context.SECURITY_PRINCIPAL, username);env.put(Context.SECURITY_CREDENTIALS, password);try {// 链接ldaplong start = System.currentTimeMillis();ctx = new InitialDirContext(env);LOG.info("认证成功 用户:{},cost:{}", username, System.currentTimeMillis() - start);return Constants.CHECK_STATUS_PASS;} catch (CommunicationException var) {}
再模拟ApacheDs返回的格式,返回给上游即可。
这里需要注意的是,后端接收到的密码格式类似于[115, 101, 99, 114, 101, 116]形式,开始很闷,这是啥东西,难道是将密码加密了,但是查看源码,没有找到解密的地方,最后灵光一现可能是密码的ascii码,我们通过简单的转译就能得到密码的明文,猜想也是对的,遇到这个问题没有立马想出来,原因是计算机基础不踏实,大脑里没有明文与ascii码的对照关系。
部署到测试环境:
因为apacheDs是maven项目,执行maven install命令,将打包后的jar包部署到测试环境,记得要在VM options中添加instance.base.dir路径,执行 java -jar xxxx.jar 命令
暴露IP + 端口 进行验证:
验证过程可以通过客户端,也可以将其提供给其他支持Ldap协议认证的软件,我是通过将测试环境IP + 端口提供给Jira服务来验证,结果肯定是没问题啦。
参考:
https://github.com/apache/directory-server
Ldap探索之路之directory-server(ApacheDs二次开发)相关推荐
- RedHat Directory Server 8.2 Installation Guide
RHDS是一套基于openldap的目录服务,当前可在官方下载的最新版本是8.2,不过下载下来的都是源代码rpm软件包,需要编译成二进制rpm软件包.我这里已经编译好了,总共12个软件包,已经包含了依 ...
- 启动weblogic的错误:Could not obtain an exclusive lock to the embedded LDAP data files directory...
http://hi.baidu.com/kaisep/item/0e4bf6ee5da001d1ea34c986 源地址 启动weblogic的错误:Could not obtain an exclu ...
- 服务器3个w目录文件夹,第 4 章 目录服务器条目 (Sun Java System Directory Server Enterprise Edition 6.2 管理指南)...
第 4 章 目录服务器条目 本章讨论如何管理目录中的数据条目.此外,还介绍如何设置引用以及如何加密属性值. 除非定义了相应的访问控制指令 (Access Control Instruction, AC ...
- 服务器禁止修改目录,目录服务器限制 (Sun Java System Directory Server Enterprise Edition 6.2 发行说明)...
不要手动更改文件权限. 在某些情况下,对已安装的 Directory Server Enterprise Edition 产品文件的权限进行更改可能会导致软件无法正常运行.只能按照产品文档中的说明或 ...
- centos directory server
centos directory server http://www.aliyun.com/zixun/content/3_12_517262.html CentOS系统安装Directory Ser ...
- LDAP(Lightweight Directory Access Protocol)介绍
LDAP(Lightweight Directory Access Protocol)介绍 LDAP是个啥? LDAP基本结构及术语 基本结构 条目(Entry) 识别名(DN) 相对识别名(RDN) ...
- ibm tivoli_IBM Tivoli Directory Server 6.0的SSL配置
介绍 安全套接字层(SSL)是一种行业标准协议,它使用对称密钥和公用密钥加密机制在Internet上提供安全通信. SSL协议在TCP / IP之上和应用协议(例如轻型目录访问协议(LDAP)和超文本 ...
- ibm tivoli_解决Tivoli Directory Server同步问题的方法
ibm tivoli IBM®Tivoli®Directory Server(TDS)是功能强大且权威的企业目录基础结构,是企业安全性的关键推动因素. 它在为诸如身份管理,门户和Web服务之类的应用程 ...
- TDS (Tivoli Directory Server)学习指南
1.概念 IBM的Tivoli Directory Server是IBM对 Lightweight Directory Access Protocol (LDAP)的实现,它可以跨平台的进行安装配置. ...
最新文章
- 2021-2027年中国透明导电膜玻璃行业市场研究及前瞻分析报告
- ubuntu18.04.4 获取当前文件路径
- 【Network Security!】服务器远程管理
- boost::function_types::is_member_object_pointer的用法测试程序
- 腾讯绝悟AI完全体限时开放体验,研究登上国际顶会与顶刊
- 聊聊JVM(八)说说GC标记阶段的一些事
- Seaborn初学指南
- Nodejs 文件上传
- Win11蓝屏100%不重启解决方法
- Spring 实践 -拾遗
- 这位程序员就这样被征服了......
- [Python+MATLAB] 在Python中使用MATLAB (持续更新中)
- STM32f407---oled屏幕配套取字模软件使用
- C#调用C语言生成的DLL“未找到入口”
- mysql存大日志_MySQL三大日志
- Android开发项目计划书
- rtk定位权限_无人机中的GPS定位、DGPS差分定位、RTK差分定位
- 内网神器-Bettercap
- 程序员的圣诞节是怎么样的?
- magisk卸载内置软件_手机刷入面具magisk授权后,ROOT权限经常丢失解决方法
热门文章
- 【网络基础】DNS是什么
- 英语知识点整理day23-谚语学习(N字母开头)
- 用playbook安装Apache,修改端口,配置ServerName,修改主页,设置开机自启
- 世界时转化为北京时!!!
- DXF00-00 时间:2021.11.30-2021.11.30 关键词1:Autodesk CAD 关键词2:脱机帮助文档 关键词3:下载及使用
- xml.parsers.expat.ExpatError: mismatched tag: line 63, column 4
- java invalidate_Swing GUI中validate(),revalidate()和invalidate()
- 平面设计和ui设计的区别:ui设计前景怎样
- 信心安全快讯丨公安部发布公安机关互联网安全监督检查规定;俄罗斯遭“围攻”被指发起网络攻击;第2季度全球7.65亿用户受到网络攻击
- NDIS LWF网络过滤驱动开发(一):LWF简介及数据结构说明