ldap 测试环境搭建与 spring ldap 开发

1 ldap 是什么

https://www.cnblogs.com/yjd_hycf_space/p/7994597.html

ldap: Lightweight Directory Access Protocol,也就是轻量目录访问协议。协议规范对应的 RFC 文档可以在 https://www.rfc-editor.org/ 或者 http://www.ldapman.org/ 中查找。

可以简单的将其理解为一个树形结构的数据库,有以下特征:

  1. 存储单元是基于属性的记录;
  2. 数据类型主要是字符型;
  3. 主要面向以快速查询为主的应用服务(查询与修改比例大于 10)
  4. 提供复杂的不同层次的访问控制

2 ldap 基本模型

2.1 数据模型

数据模型 = (名称,地址,类型,值)

在 ldap 中数据是以树状方式来组织和存储的,树状结构中的每一个节点都对应一个 ldap 条目(entry),entry 的数据模型对应为:

(名称,地址,类型,值)= (rdn,dn,[ objectclass_1, objectclass_2, ….], { key = value}).

ldap 中的 entry 有的类型是通过 objectclass 来定义的,每个 ObjectClass 由多个属性类型(attribute type)组成;对象类(objectclass)和属性类型(attribute type)都有继承的概念。

在 ldap 中把对象类,属性类型,语法和匹配规则统称为 schema;可以简单的这么理解:

  • objectclass 对应于关系数据库中的 table
  • attribute type 对应于关系数据库中的 column type

ldap 已经预定义了很多 schema,也可以根据需要自定义 schema。

ldap 为了加快查询速度,在 schema 中有匹配规则的概念,针对不同的数据类型,可以提供不同的匹配方法,如针对字符串类型的相等、模糊、大于、小于,都可以提供自己的匹配规则。

2.2 命名模型

ldap 中的命名模型,DN(distinguish name),RDN(Relative Distinguished Name)。

DN 是 ldap entry 在整个树中的唯一名称标识,RDN 是节点名称,可以简单的用文件系统中文件路径和文件名的概念来理解,DN 就是文件在系统中的绝对路径,比如 /opt/china/baidu/develop/xiaowang,而 RDN 就是文件名称 xiaowang。

2.3 功能模型

在 ldap 中有多种操作:

  • 查询:搜索,比较
  • 更新:add,delete,modify
  • 认证:bind,unbind
  • others

2.4 安全模型

ldap 中的安全模型主要通过身份认证、安全通道和访问控制来实现。

3 openLDAP服务器

openLDAP 官网: http://www.openldap.org/
用户手册:http://www.openldap.org/doc/admin24/OpenLDAP-Admin-Guide.pdf

openLDAP 是 ldap 的开源实现.

首先按照默认配置安装 openLDAP。
配置: slapd.conf

suffix “dc=example,dc=com”
rootdn “cn=Manager,dc=example,dc=com”

spring ldap 中的 ContextSource 则对应如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ldap="http://www.springframework.org/schema/ldap"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">

   <ldap:context-source
          url="ldap://localhost:389"
          base="dc=example,dc=com"
          username="cn=Manager"
          password="secret" />

   <ldap:ldap-template id="ldapTemplate" />

   <bean id="personRepo" class="com.example.repo.PersonRepoImpl">
      <property name="ldapTemplate" ref="ldapTemplate" />
   </bean>
</beans>

如果通过 LDAP Admin 来访问 openLdap,建立 connection 时,需要配置如下:
这里写图片描述

4 Spring LDAP

官网: http://projects.spring.io/spring-ldap/

Spring LDAP 基于 ldapTemplate 来简化 ldap 操作,用户在使用 ldapTemplate 时,就无需考虑资源的释放等问题了,类似于 JdbcTemplate。

  1. 提供 LdapTemplate 来消除一些重复的框架代码;
  2. 提供了一套规范的、结构化的异常体系;
  3. 提供了一些动态构建 LDAP filters 和 Distinguished Names 的工具类;
  4. 客户端 LDAP 事务管理;
  5. ….

4.1 构建 LDAP queries,并使用 AttributeMapper 进行查询和搜索

ldapTemplate.search(
         query().where("objectclass").is("person"),
         new AttributesMapper<String>() {
            public String mapFromAttributes(Attributes attrs)
               throws NamingException {
               return (String) attrs.get("cn").get();
            }
         });

可以通过 query() 构建复杂的过滤规则,类似于 SQL,比如:

LdapQuery query = query().base("dc=261consulting,dc=com")
                         .attributes("cn", "sn")
                         .where("objectclass").is("person")
                         .and("sn").is("tom");

AttributesMapper 是一个回调接口,如果想要获取 entity 的 dn 信息的话,可以使用 ContextMapper。

4.2 动态构建 DN

LdapName 是 J2SE 中定义的 DN 接口,但是比较弱,Spring ldap 又提供了其他几个工具类来辅助对 DN 的操作,比如 LDAPNameBuilder, LdapUtils。

final String BASE_DN = "dc=example,dc=com";
Name name = LdapNameBuilder.newInstance(BASE_DN)
      .add("c", p.getCountry())
      .add("ou", p.getCompany())
      .add("cn", p.getFullname())
      .build();

需要注意 ldap 中节点的顺序,比如 DN = ‘cn=xiaoming, ou=baidu, c=china, dc=example, dc=com’。

name.get(0) == "c=china";
name.get(1) == "ou=baidu";
name.get(2) == "cn=xiaoming"; 

4.3 添加,删除与更新

在 ldap 中通过 Binding 来实现数据节点的添加,通过 unbinding 来实现数据节点的删除。

ldapTemplate.bind(dn, null, attributes);
ldapTemplate.unbind(dn);

其中 attributes 就是 entry 的属性数据,可以通过如下方式构建:1

 Attributes attrs = new BasicAttributes();
      BasicAttribute ocattr = new BasicAttribute("objectclass");
      ocattr.add("top");
      ocattr.add("person");
      attrs.put(ocattr);
      attrs.put("cn", "Some Person");
      attrs.put("sn", "Person");
      return attrs;

数据更新有两种方式:rebind,和 modifyAttributes,其中 rebind 就是先 unbind 再 bind,稍显暴力。另外还可以通过 DirContextOperations 来简化 modifyAttributes 的使用。

4.4 属性映射,ODM

Object-Directory Mapping, 与 Hibernate 的功能类似,就是将 ldap 中的 entry 映射为 java 中的对象。

。。。。

4.5 用户认证: User Authentication

可以通过 ldapTempalate 中的 authenticate 接口来实现用户认证:

ldapTemplate.authenticate(query().where("uid").is("john.doe"), "secret");

认证失败时会抛出异常!!

5 总结

把 ldap 当成数据库来看就对了,想更详细的了解 ldap 规范和 spring ldap,就去查阅官网吧!

猜你喜欢

转载自blog.csdn.net/antony1776/article/details/80317035