SpringBoot --- 整合Ldap
整理不易,不喜勿喷。谢谢
SpringBoot — 整合Ldap.
SpringBoot — 整合Spring Data JPA.
SpringBoot — 整合Elasticsearch.
SpringBoot — 整合spring-data-jpa和spring-data-elasticsearch.
SpringBoot — 整合thymeleaf.
SpringBoot — 注入第三方jar包.
SpringBoot — 整合Redis.
Springboot — 整合slf4j打印日志.
Springboot — 整合定时任务,自动执行方法.
Springboot — 配置多数据源,使用JdbcTemplate以及NamedParameterJdbcTemplate.
Sprignboot — 详解pom.xml中build和profile.
SpringBoot — 监控.
SpringBoot — 缓存Cache/Redis.
SpringBoot与Zookeeper.
Git的使用.
1.介绍
缩写 | 全称 | 内容 |
---|---|---|
DC | Domain Component | 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com |
UID | User Id | 用户ID songtao.xu(一条记录的ID) |
OU | Organization Unit | 组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织) |
CN | Common Name | 公共名称,如“Thomas Johansson”(一条记录的名称) |
SN | Surname | 姓,如“许” |
DN | Distinguished Name | “uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一) |
RDN | Relative dn | 相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson” |
- Ldap连接服务器的连接字串格式为:ldap://servername/port
- 例如:CN=test,OU=developer,DC=domainname,DC=com
在上面的代码中 cn=test 可能代表一个用户名,ou=developer 代表一个 active directory 中的组织单位。这句话的含义可能就是说明 test 这个对象处在domainname.com 域的 developer 组织单元中。
2.代码
2.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.nolan</groupId>
<artifactId>spring-boot-ldap</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-ldap</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2 配置文件
server.port=8086
spring.ldap.urls=ldap://xxxx:xxxx
spring.ldap.base=OU=xxx,DC=xxx,DC=xxx
spring.ldap.username=CN=xxxx,OU=xxxx,OU=Users,OU=xxx,OU=xx,OU=xxx,DC=xxxx,DC=corp
spring.ldap.password=Mxxxx
2.3 代码
1.service
@Service
public interface LdapService {
List<LdapUser> getPersonList();
List<LdapDept> getDeptList();
boolean authenticate(String user, String pwd);
}
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.stereotype.Service;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import java.util.List;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
@Service
public class LdapServiceImpl implements LdapService {
@Autowired
private LdapTemplate ldapTemplate;
/**
* 获得域用户
*/
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public List<LdapUser> getPersonList() {
//下面也可以使用filter查询方式,filter 为(&(objectClass=user)(!(objectClass=computer))
return ldapTemplate.search(query().where("objectclass").is("user").and("objectclass").not().is("computer"),
new AttributesMapper() {
@Override
public LdapUser mapFromAttributes(Attributes attr) throws NamingException, javax.naming.NamingException {
//如果不知道ldap中有哪些属性,可以使用下面这种方式打印
System.out.println("==============start ldap person attribute==============================");
NamingEnumeration<? extends Attribute> att = attr.getAll();
while (att.hasMore()) {
Attribute a = att.next();
System.out.println(a.getID());
}
System.out.println("==============上面是ldap person attribute==============================");
LdapUser person = new LdapUser();
String distingugihedName = (String) attr.get("distinguishedName").get();
person.setUserName((String) attr.get("sAMAccountName").get());
person.setRealName((String) attr.get("cn").get());
String departmentName = StringUtils.substringAfter(distingugihedName.split(",")[1], "OU=");
person.setUnitName(departmentName);
if (attr.get("description") != null) {
person.setDescription((String) attr.get("description").get());
}
if (attr.get("mobile") != null) {
person.setPhone((String) attr.get("mobile").get());
}
if (attr.get("telephoneNumber") != null) {
person.setTelephone((String) attr.get("telephoneNumber").get());
}
if (attr.get("userPrincipalName") != null) {
person.setEmail((String) attr.get("userPrincipalName").get());
}
return person;
}
});
}
/**
* 获得部门
*/
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public List<LdapDept> getDeptList() {
return ldapTemplate.search(
query().where("objectclass").is("organizationalunit").or("objectclass").is("organization"),
new AttributesMapper() {
@Override
public LdapDept mapFromAttributes(Attributes attr) throws NamingException {
//如果不知道ldap中有哪些属性,可以使用下面这种方式打印
// NamingEnumeration<? extends Attribute> att = attr.getAll();
//while (att.hasMore()) {
// Attribute a = att.next();
// System.out.println(a.getID());
//}
LdapDept dept = new LdapDept();
dept.setDeptId(attr.get("ou").toString().split(":")[1].trim());
if (attr.get("description") != null) {
dept.setDeptName(attr.get("description").toString().split(":")[1].trim());
}
return dept;
}
});
}
/**
* 根据用户名密码验证
*
* @param username 用户名
* @param pwd 密码
* @return
*/
@SuppressWarnings("unchecked")
@Override
public boolean authenticate(String username, String pwd) {
DirContext ctx = null;
System.out.println(username + ":" + pwd);
try {
//调用ldap 的 authenticate方法检验
String filter = "(&(objectclass=user)(!(objectClass=computer))(sAMAccountName=" + username + "))";
boolean authenticate = ldapTemplate.authenticate("", filter, pwd);
return authenticate;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
LdapUtils.closeContext(ctx);
}
}
}
2.entity
@Data
public class LdapDept {
private String deptId;
private String deptName;
}
@Data
public class LdapUser {
private String userName;
private String email;
private String phone;
private String telephone;
private String realName;
private String unitName;
private String description;
}
3.config
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class LdapConfig {
private LdapTemplate ldapTemplate;
@Value("${spring.ldap.urls}")
private String url;
@Value("${spring.ldap.base}")
private String base;
@Value("${spring.ldap.username}")
private String username;
@Value("${spring.ldap.password}")
private String password;
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
Map<String, Object> config = new HashMap();
contextSource.setUrl(url);
contextSource.setBase(base);
contextSource.setUserDn(username);
contextSource.setPassword(password);
// 解决乱码
config.put("java.naming.ldap.attributes.binary", "objectGUID");
contextSource.setPooled(true);
contextSource.setBaseEnvironmentProperties(config);
return contextSource;
}
@Bean
public LdapTemplate ldapTemplate() {
if (null == ldapTemplate) {
ldapTemplate = new LdapTemplate(contextSource());
}
return ldapTemplate;
}
}