一、何为ldap
LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。基本知识请点击传送门:https://segmentfault.com/a/1190000002607140
二、UnboundID简介
UnboundID LDAP SDK提供了一套快速、强大、用户友好并且开源的Java API来与LDAP目录服务器交互。与其它基于Java的LDAP APIs相比,它具有更好的性能、更易于使用,功能更多。而且还是唯一个不断有活跃开发和增强的SDK。官网地址:https://www.ldap.com/unboundid-ldap-sdk-for-java
三、项目背景
为何选择ldap目录协议?
在企业内部,用户中心是很重要的,但是这个针对客户爸爸的。员工作为企业的支柱,也需要一个好的员工用户中心,来管理员工信息、企业内部系统的账号权限、员工成长以及评估体系。帮助员工提高工作效率,明确自己的不足,达到个人和企业双赢。ldap目录协议适合读的特性对于员工信息有非常好的支持。
四、UnboundID的使用
组织结构:可以看到采用的是ou的tree型结构,uid作为叶子节点附着在各个ou的分支下面。
OU=部门
uid=员工
属性转换:
部门:
ou=部门id(唯一标识)
description=部门名称
员工:
account=账号 cn=姓名 displayName=别名(互联网公司风行的花名) employeeNumber=工号 mail=公司邮箱 mobile=手机号 sn=姓(默认为空字符串) title=岗位 userPassword密码 uid=员工id(唯一标识) |
1.jar包依赖
<dependency> <groupId>com.unboundid</groupId> <artifactId>unboundid-ldapsdk</artifactId> <version>3.2.0</version> </dependency>
LDAPConnection connection = new LDAPConnection(ldapHost, ldapPort, ldapBindDN, ldapPassword);
3. 查询
基本的查询,可以查询ou和uid等。dn为需要查询的索引语句,filter为查询的条件,相当于sql中的where等,scope为查询的范围。
public static List<SearchResultEntry> queryLdap(String dn, Filter filter, SearchScope scope) { List<SearchResultEntry> result = new ArrayList<SearchResultEntry>(); try { openConnection(); SearchRequest searchRequest = new SearchRequest(dn, scope, filter); searchRequest.addControl(new SubentriesRequestControl()); SearchResult searchResult = connection.search(searchRequest); for (SearchResultEntry entry : searchResult.getSearchEntries()) { result.add(entry); } } catch (Exception e) { LOG.error("query failed.", e); throw new BaseRuntimeException(e); } return result; }
4.添加
添加ou或者uid等。dn一样为需要添加到的索引语句,attributes为属性集合(uid的sn属性为必填,但是此处我选择填空字符串)
public static LDAPResult createEntry(String dn, Collection<Attribute> attributes) { LDAPResult result = null; try { // 连接LDAP openConnection(); SearchResultEntry entry = connection.getEntry(dn); if (entry == null) { // 不存在则创建 result = connection.add(dn, attributes); } } catch (Exception e) { LOG.error("create entry failed", e); throw new BaseRuntimeException(e); } return result; }
5. 修改属性
修改ou或者uid的属性,注意,此处不可以直接修改ou和uid(因为这两个属性在dn中,如需修改使用modifyDN)
public static LDAPResult modifyEntry(String dn, Map<String, String> attrs) { LDAPResult result = null; if (attrs.size() == 0) { return result; } try { // 连接LDAP openConnection(); SearchResultEntry entry = connection.getEntry(dn); if (entry == null) { LOG.info("entry is not exist.dn:{}", dn); return result; } // 修改信息 ArrayList<Modification> md = new ArrayList<Modification>(); for (String key : attrs.keySet()) { md.add(new Modification(ModificationType.REPLACE, key, attrs.get(key))); } result = connection.modify(dn, md); } catch (Exception e) { LOG.error("modify entry failed", e); throw new BaseRuntimeException(e); } return result; }
6. 删除
此处删除,我选择直接物理删除,因为数据库中也保存信息,数据库中做标记删除即可。
public static LDAPResult deleteEntry(String dn) { LDAPResult result = null; try { // 连接LDAP openConnection(); SearchResultEntry entry = connection.getEntry(dn); if (entry == null) { LOG.info("entry is not exist.dn:{}", dn); return result; } // 物理删除 result = connection.delete(dn); } catch (Exception e) { LOG.error("delete entry failed", e); throw new BaseRuntimeException(e); } return result; }
结束语:
ldap作为目录协议,可以良好的集成jenkins、wiki、jira、nas、wifi以及企业内部系统的用户中心。集成时Jenkins等工具时,只需在配置中配置好ldap数据源即可。对于企业内部系统,ldap可以作为单点登录的数据源。后续工具的具体配置以及基于ldap的单点登录方案后续给出。