springboot操作ldap全过程
作者:请君择日再来
以下可能不是特别深入讲解,只是开发用到,浅谈一下。尽量用数据库的方式去对应
LDAP:轻量级目录访问协议。
微软的AD域,openldap之类的都可以通过LDAP协议去连接访问。
ad(active diretory)活动目录;openldap就是ldap协议的具体实现。
在这里把他们当成一个数据库来看待,目录存储数据库。
如下图,就是openldap的层级图。
1. 专有名词
关于这一块涉及到很多专有名词这里简单谈一下。
- dc:表示域名的意思,就是一个域的名称,可以当成数据库中的库名来看待。
- ou:组织单元,就像一层层的文件夹看待,这个ou可以有多个层级,就是ou下还可以有ou,当成数据库中的表看待
- cn:用户名或服务器名。就相当于数据库某一行用户信息的主键
- dn:相当于绝对路径,由cn+ou+dc组成。如上图alice的dn就是 cn=alice,ou=school,dc=demo,dc=com
每个用户是有多个属性值的,就好比数据库中的字段,一行用户有多个字段信息
2. springboot连接
导入依赖
<!--ldap--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-ldap</artifactId> </dependency>
application.properties配置文件。这里连接的账户不是ldap目录下管理的用户,就是别用上述的alice这种用户去连接。
#AD认证 spring.ldap.urls=ldap://127.0.0.1:389 spring.ldap.username=cn=admin,dc=demo,dc=com spring.ldap.password=123456 spring.ldap.base=ou=school,dc=demo,dc=com
自定义配置类
@Configuration public class LdapConfig { @Value("${spring.ldap.urls}") private String ldapUrl; @Value("${spring.ldap.username}") private String userName; @Value("${spring.ldap.password}") private String password; @Bean public LdapContextSource ldapContextSource() { LdapContextSource source = new LdapContextSource(); source.setUrl(ldapUrl); source.setUserDn(userName); source.setPassword(password); return source; } @Bean public LdapTemplate ldapTemplate() { return new LdapTemplate(ldapContextSource()); } }
基本上如上配置就可以操作了
测试是否可以连接,直接调用接口,能成功连接就会输出数据,无法连接会出现认证异常。
3. 按条件查询
先上案例,查询cn属性值为alice的。这里没有指定返回的属性有哪些,所以返回的就是所有属性。稍后再解释Person和PersonMapper
Person就是一个普通实体类,就像平时查询数据库数据时都是用实体类接收数据
@Data public class Person { private String cn; private String displayName; private String givenName; private String eMail; private String ou; }
PersonMapper类就不一样了,必须继承AttributesMapper类,实现mapFromAttributes方法。
当ldapTemplate通过条件筛选出数据时,一行数据就会调用一次这个方法,attributes带有查出的属性值
@Slf4j public class PersonMapper implements AttributesMapper<Person> { @Override public Person mapFromAttributes(Attributes attributes) throws NamingException { log.info(attributes.toString()); Person result = new Person(); result.setCn(attributes.get("cn").get().toString()); return result; } }
筛选方式有很多,必须有筛选条件才能查询。
加上attributes(new String[]{"cn", "mail"}),就只会查询出这两个属性值
LdapQuery query = LdapQueryBuilder.query() .base(base) .searchScope(SearchScope.SUBTREE) .attributes(new String[]{"cn", "mail"}) .where("cn") .is("alice");
可以用filter筛选,也是cn属性值为alice的筛选条件。
LdapQuery query = LdapQueryBuilder.query() .base(base) .searchScope(SearchScope.SUBTREE) .filter("(cn=alice)");
base下所有内容带有objectClass属性,都会被查出来。
如果base自身也带有,自身也会被查出来
LdapQuery query = LdapQueryBuilder.query() .base(base) .searchScope(SearchScope.SUBTREE) .filter("(objectClass=*)");
多条件筛选,cn为alice并且mail为123@qq.com的内容。
LdapQuery query = LdapQueryBuilder.query() .base(base) .searchScope(SearchScope.SUBTREE) .filter("(&(cn=alice)(mail=123@qq.com))");
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。