赞
踩
目录
2.连接LDAP服务器配置类,初始化连接,创建LdapTemplate
- <!--spring security ldap支持 做认证用,若不做认证只是测试连一下,可以不依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
- <!--ldap依赖,版本建议和boot版本一致-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-ldap</artifactId>
- </dependency>
- <!-- unboundid-ldapsdk主要是为了在这里使用嵌入式的LDAP服务端来进行测试操作,所以scope设置为了test,
- 实际应用中,会连接真实的、独立部署的LDAP服务器,不需要此项依赖。 -->
- <dependency>
- <groupId>com.unboundid</groupId>
- <artifactId>unboundid-ldapsdk</artifactId>
- <scope>test</scope>
- </dependency>
在 Spring Boot 应用程序中,您可以使用 application.properties
或 application.yml
来配置嵌入式 LDAP 服务器。当您使用 spring.ldap.embedded
配置属性时,Spring Boot 会尝试启动一个内嵌的 LDAP 服务器,并加载指定的 LDIF 文件作为初始数据。
application.yml
配置如下内容:
- spring:
- ldap:
- embedded:
- ldif: classpath:ldap-server.ldif
- base-dn: dc=testldap,dc=com
- #classpath 意味着LDIF文件可以在任何标记为类路径的位置找到,而src/main/resources目录下的内容在构建过程中会被自动加入到类路径中。
这里是如何读取配置并启动内嵌的 LDAP 服务器:
ldif: 这个字段指向一个 LDIF (LDAP Data Interchange Format) 文件。在这个例子中,它指向类路径下的
ldap-server.ldif
文件。Spring Boot 将会在应用启动时从这个文件加载数据到内嵌的 LDAP 服务器中。请确保该 LDIF 文件存在于您项目的资源目录下,例如src/main/resources/ldap-server.ldif
。base-dn: 这是内嵌 LDAP 服务器使用的基本目录名称(Base DN)。在此示例中,所有的 LDAP 数据都将被加载至根目录
dc=testldap,dc=com
下。
当 Spring Boot 应用程序启动时,它会自动配置一个内嵌的 LDAP 服务器并加载 ldap-server.ldif
文件中定义的数据。不需要编写任何额外的代码来启动或初始化 LDAP 服务器;Spring Boot 的自动配置功能会处理这一切。
需要引入两个相关依赖:
unboundid-ldapsdkspring-boot-starter-data-ldap
通过这种配置,您就可以在本地开发环境中模拟 LDAP 服务,而无需连接到真实的 LDAP 服务器。这在进行集成测试或本地开发时非常有用
- spring: #springboot的配置
- ldap:
- embedded:
- ldif: classpath:ldap-server.ldif
- base-dn: dc=testldap,dc=com
- port:8389 #默认839
如果ldap-server.ldif和application.yml在相同文件夹下,可以用相对路径,可以不加classpath
我这里配置的时候使用的是nacos 肯定不在相同文件夹下,需要加classpath
在src/test/resources
目录下创建ldap-server.ldif文件
文件内容
dn: dc=testldap,dc=com objectClass: top objectClass: domain dn: ou=users,dc=testldap,dc=com objectclass: top objectclass: organizationalUnit ou: people dn: uid=1,ou=users,dc=testldap,dc=com objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: zhangsan sn: zhang uid: 1 userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
-
- import com.fasterxml.jackson.annotation.JsonIgnore;
- import lombok.Data;
- 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;
-
- /**
- * @version v1.0
- * @className LdapUser
- * @description 与 LADP存储内容进行映射
- */
- @Entry(
- base = "ou=users,dc=testldap,dc=com",
- objectClasses = {"top", "person", "organizationalPerson", "inetOrgPerson"}
- )
- @Data
- public class LdapUserinfo {
- @Id
- @JsonIgnore
- private Name id; // LDAP Distinguished Name (DN)
-
- @Attribute(name = "cn") // Common Name
- private String realName;
-
- @Attribute(name = "mobile") // Mobile number
- private String phone;
-
- @Attribute(name = "userPassword")
- private String password;
-
- @Attribute(name = "mail") // E-mail address
- private String emailAddr;
-
- @Attribute(name = "uid")
- private String userId;
-
- }
-
- import cn.hutool.json.JSONUtil;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.ldap.core.AttributesMapper;
- import org.springframework.ldap.core.LdapTemplate;
- import org.springframework.ldap.filter.EqualsFilter;
- import org.springframework.ldap.query.ContainerCriteria;
- import org.springframework.ldap.query.LdapQueryBuilder;
- import org.springframework.stereotype.Component;
-
- /**
- * @version v1.0
- * @className LdapUtil
- * @date 2024/5/14
- */
- @Slf4j
- @Component
- public class LdapUtil {
- @Autowired
- private LdapTemplate ldapTemplate;
- @Value("${spring.ldap.embedded.base-dn}")
- private String baseRoot;//从nacos读取的 为了验证能否正常读取nacos,可以不写
-
-
- public LdapUserinfo findUser(String base,String userId, String password) {
- // 根据uid 和密码 查询用户是否存在
- log.info("---findUser---userName={} password={} baseRoot={}", userId,password,baseRoot);
- LdapUserinfo userinfo = null;
- EqualsFilter filter = new EqualsFilter("uid", userId);
- base = "ou=users,dc=testldap,dc=com";
- boolean bool = ldapTemplate.authenticate(baseRoot, filter.toString(), password);
- if (bool) {
- // 构建查询条件
- LdapQueryBuilder builder = LdapQueryBuilder.query();
- // 根据 uid查询
- builder.where("uid").is(userId);
- // 注意LdapUserinfo 类,一定要跟 ldap协议中的属性名称对应
- userinfo = ldapTemplate.findOne(builder, LdapUserinfo.class);
- log.info("LdapUserinfo:" + JSONUtil.toJsonStr(userinfo));
- } else {
- log.info("未查询到用户");
- }
- return userinfo;
- }
-
- public void findUser() {
- // 构建查询条件
- LdapQueryBuilder builder = LdapQueryBuilder.query();
- //builder.base("dc=testldap,dc=com"); yml中已经指定了,这里不需要再指定,重复指定会导致路径解析问题
- // 根据 uid查询
- builder.where("cn").is("admin");
- // 注意LdapUserinfo 类,一定要跟 ldap协议中的属性名称对应
- AdminUser userinfo = ldapTemplate.findOne(builder, AdminUser.class);
- log.info("LdapUserinfo:" + JSONUtil.toJsonStr(userinfo));
- }
-
- }
注:yml中已经指定了base,不需要再指定,重复指定会导致路径解析问题。尽量为空
将testldap.ldif中的内容打印出来了
debug时测试内置服务器连接,此时本地的嵌入式服务器是联通的
参考链接:Spring Boot中使用LDAP来统一管理用户信息_ldapquery-CSDN博客
mac安装openldap详见:Mac上安装OpenLDAP服务器详细教程(Homebrew安装和自带的ldap)-CSDN博客
- spring: #springboot的配置
- ldap:
- urls: ldap://localhost:389
- base: dc=testldap,dc=com
- username: cn=admin,dc=testldap,dc=com
- password: secret
-
- 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;
-
- /**
- * @version v1.0
- * @className LdapConfig
- * @date 2024/5/21
- * @description 开发配置类LdapConfiguration,初始化连接,创建LdapTemplate
- */
- @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);// 例:管理员DN
- contextSource.setPassword(password);// 例:管理员密码
- // 解决乱码
- config.put("java.naming.ldap.attributes.binary", "objectGUID");
- // 启动时不立即初始化(lazy connection initializing),直到第一次LDAP操作
- contextSource.setPooled(true);
- // 调用afterPropertiesSet方法是必须的,它会处理配置并创建初始连接
- contextSource.setBaseEnvironmentProperties(config);
- return contextSource;
- }
- @Bean
- public LdapTemplate ldapTemplate() {
- if (null == ldapTemplate) {
- ldapTemplate = new LdapTemplate(contextSource());
- }
- return ldapTemplate;
- }
- }
根据LDAP 数据结构,你可以创建一个映射到 admin
用户条目的 Java 类。这个类需要使用 Spring LDAP ODM(Object-Directory Mapping)来映射 LDAP 条目的属性到 Java 对象的属性。
根据ldif文件条目设置字段
- # testldap.com
- dn: dc=testldap,dc=com
- objectClass: top
- objectClass: dcObject
- objectClass: organization
- o: Example Organization
- dc: testldap
-
- # admin, testldap.com
- dn: cn=admin,dc=testldap,dc=com
- objectClass: organizationalRole
- cn: admin
@Entry(objectClasses = {"organizationalRole"})
-
- import lombok.Data;
- import org.springframework.ldap.odm.annotations.Attribute;
- import org.springframework.ldap.odm.annotations.Entry;
- import org.springframework.ldap.odm.annotations.Id;
-
- import javax.naming.ldap.LdapName;
-
- @Entry(objectClasses = {"organizationalRole"})
- @Data
- public class AdminUser {
- @Id
- private LdapName dn; // LDAP Distinguished Name (DN)
-
- @Attribute(name = "cn")
- private String commonName;
- }
- public void findUser() {
- // 构建查询条件
- LdapQueryBuilder builder = LdapQueryBuilder.query();
- //builder.base("dc=testldap,dc=com");
- // 根据 uid查询
- builder.where("cn").is("admin");
- // 注意LdapUserinfo 类,一定要跟 ldap协议中的属性名称对应
- AdminUser userinfo = ldapTemplate.findOne(builder, AdminUser.class);
- log.info("LdapUserinfo:" + JSONUtil.toJsonStr(userinfo));
- }
打印结果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。