技术栈简介
Springboot就不用多介绍了吧,相信搜索到这篇文章的人都是Springboot熟手了。
LDAP(Light Directory Access Portocol),它是一款标准的轻量级目录访问协议。从其它地方搬来一些它的简介如下:
- 目录是一个为查询、浏览和搜索而优化的数据库,它采用树状结构组织数据,类似于文件目录一样
- 目录数据库与关系数据库不同,它有优异的读性能,但是写入性能差,并且没有事务处理、回滚等复杂功能,不适合存储频繁修改的数据
所以,LDAP天生是用来查询的,就像它的名字一样。LDAP相关概念请自行百度。
Springboot集成
Springboot提供了便捷的LDAP开发工具包,引入如下依赖即可:
<!-- LDAP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
然后配置LDAP服务信息:
spring:
ldap:
urls: ldap://***.***.***.***:389
username: cn=<ldapuser>,${spring.ldap.base}
password: <ldap_password>
base: CN=Users,DC=demo,DC=com
以上配置根据自己的LDAP服务修改。
Springboot提供了LdapTemplate、LdapRepository等封装工具类用于访问LDAP服务。首先定义LdapUser对象,用于数据的组装。
import lombok.Data;
import lombok.ToString;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import javax.naming.Name;
@Data
@ToString
@Entry(objectClasses = {"person"}, base = "CN=Users,DC=demo,DC=com")
public class LdapUser {
@Id
private Name id;
@Attribute(name = "cn")
private String cn;
@Attribute(name = "sn")
private String sn;
@Attribute(name="mail")
private String mail;
}
objectClasses可以设置多个值,用wireshark抓包查看有"top", "person", "user", "organizationalPerson"等这些类别,也可以在LDAP中自定义类别,查询时一定要设置正确的类型才能查询到结果。
LdapRepository方式
自定义访问接口:
import org.springframework.data.ldap.repository.LdapRepository;
public interface LdapUserRepository extends LdapRepository<LdapUser> {
}
定义该接口后,在springboot中即可自动装载并使用。
LdapTemplate方式
无需任何操作,直接装载LdapTemplate对象即可使用。
两种方式使用如下:
@SpringBootTest
class AiguardApplicationTests {
@Autowired
private LdapUserRepository ldapUserRepository;
@Autowired
private LdapTemplate ldapTemplate;
@Test
public void getAll() {
ldapUserRepository.findAll().forEach(System.out::println);
List<String> res = ldapTemplate.list("");
System.out.println(res.size());
}
@Test
public void getOne() {
EqualsFilter filter = new EqualsFilter("sAMAccountName", "yaozong.li");
LdapQuery query = LdapQueryBuilder.query()
.where("userPrincipalName").is("yaozong.li@demo.com")
.or("sAMAccountName").is("yaozong.li");
LdapUser person = ldapTemplate.findOne(query, LdapUser.class);
System.out.println(person);
}
@Test
public void authenticationTest() {
boolean success = ldapTemplate.authenticate("", "(sAMAccountName=yaozong.li)", "*********");
System.out.println(success);
}
}
?LDAP协议交互时序
- 鉴权,如上的鉴权测试,LdapTemplate封装了authenticate方法,通过网络抓包发现,该方法分三步,发起了三次网络请求:
- 登录
- 查询人员
- 人员鉴权校验
2. 查询人员,如上查询一个人员信息,该方法分两步,发起了两次网络请求:
- 登录
- 查询人员
?可以看到,最终发送给LDAP服务器的查询条件是红框里面的内容,是经过组装的。详细查询语法请自行百度。
|