java连接ldap实现查询

在这里插入图片描述

文章目录

  • 一、项目背景
  • 二、准备工作
  • 三、验证结果
  • 四、易错点讲解
    • 易错点1:java: 无法访问org.springframework.ldap.core.LdapTemplate
    • 易错点2:java: 无法访问org.springframework.context.ConfigurableApplicationContext
    • 易错点3:[LDAP: error code 34 - invalid DN]
    • 易错点4:LDAP: error code 32 - No Such Object
    • 易错点5:配置文件介绍

一、项目背景

我们公司原项目是Spring或者SpringBoot项目,现在假设收购了一家公司(人家所有账户信息都保存在ldap数据库中),现在需要把它集成进来,最终实现项目支持两种方式认证:

  • 如果是http协议执行从mysql数据库查询账户,校验用户+密码
  • 另一种如果是ldap协议,则从ldap中查询账户,校验用户+密码

目前我的项目版本:

  • Spring版本:5.3.15
  • SpringBoot版本:2.6.3

二、准备工作

test.ldif文件 用于创建账户

注意点1:必须先创建组,然后才能创建组下用户,不然cn=ldapUser1,ou=Develop,ou=Hytera,dc=yaobili,dc=com这么写是非法的
注意点2:我创建了2个账户,ldapUser1账户1密码未加密Eadmin123456,ldapUser2账户2密码加密了设置的{SSHA}J3NuHvl3O8LdPuV2QFYc2pPy3wq1EzIN,它两都是相同的密码(即Eadmin123456和{SSHA}J3NuHvl3O8LdPuV2QFYc2pPy3wq1EzIN是等价的)
注意点3:其中的{SSHA}代表采用SHA-1加密方式对密码进行了加密,详情可在服务器执行如下命令

[root@localhost ~]# slappasswd -s Eadmin123456
{SSHA}J3NuHvl3O8LdPuV2QFYc2pPy3wq1EzIN
创建组织架构
dn:ou=Hytera,dc=yaobili,dc=com
objectClass:organizationalUnit
ou:Hyteradn:ou=Develop,ou=Hytera,dc=yaobili,dc=com
objectClass:organizationalUnit
ou:Develop创建用户
dn: cn=ldapUser1,ou=Develop,ou=Hytera,dc=yaobili,dc=com
objectClass: inetOrgPerson
cn: ldapUser1
username: ldapUser1
userPassword: Eadmin123456
memberOf: ou=Develop,ou=Hytera,dc=yaobili,dc=comdn: cn=ldapUser2,ou=Develop,ou=Hytera,dc=yaobili,dc=com
objectClass: inetOrgPerson
cn: ldapUser2
username: ldapUser2
userPassword: Eadmin123456
memberOf: ou=Develop,ou=Hytera,dc=yaobili,dc=comdn: cn=ldapUser4,ou=Develop,ou=Hytera,dc=yaobili,dc=com
objectClass: inetOrgPerson
cn: ldapUser4
username: ldapUser4
userPassword: {SSHA}J3NuHvl3O8LdPuV2QFYc2pPy3wq1EzIN
memberOf: ou=Develop,ou=Hytera,dc=yaobili,dc=com

成功后页面长这样:

在这里插入图片描述

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-test</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>Ldap-test</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--解决@RestController注解爆红--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>${spring.boot.starter.web.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!--测试类--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>${spring.boot.starter.test.version}</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-ldap</artifactId><version>2.6.3</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-ldap</artifactId><version>2.6.3</version></dependency><dependency><groupId>com.sun</groupId><artifactId>ldapbp</artifactId><version>1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.ldap</groupId><artifactId>spring-ldap-core</artifactId><version>2.4.0</version></dependency><dependency><groupId>org.apache.directory.api</groupId><artifactId>api-all</artifactId><version>2.0.0</version></dependency></dependencies>
</project>

application.properties

server.port=8020spring.ldap.urls=ldap://10.110.38.162:389
spring.ldap.username=cn=admin,dc=yaobili,dc=com
spring.ldap.password=123456
spring.ldap.base=dc=yaobili,dc=com

LdapConfiguration配置类

package com.ldap.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import java.util.Objects;/*** LDAP 的自动配置类* @Author 211145187* @Date 2024/5/21 16:44**/
@Configuration
public class LdapConfiguration {private static Logger logger = LoggerFactory.getLogger(LdapConfiguration.class);private LdapTemplate ldapTemplate;@Value("${spring.ldap.urls}")private String dbUrl;@Value("${spring.ldap.username}")private String username;@Value("${spring.ldap.password}")private String password;@Value("${spring.ldap.base}")private String base;@Beanpublic LdapContextSource contextSource() {LdapContextSource contextSource = new LdapContextSource();Map<String, Object> config = new HashMap();contextSource.setUrl(dbUrl);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;}@Beanpublic LdapTemplate ldapTemplate(LdapContextSource contextSource) {if (Objects.isNull(contextSource)) {throw new RuntimeException("ldap contextSource error");}if (null == ldapTemplate) {ldapTemplate = new LdapTemplate(contextSource);}return ldapTemplate;}
}

LdapUserAttributeMapper映射类

package com.ldap.mapper;import com.ldap.entity.LdapUser;
import org.springframework.ldap.core.AttributesMapper;import javax.naming.NamingException;
import javax.naming.directory.Attributes;/*** 将ldap返回的结果,转成指定对象*/
public class LdapUserAttributeMapper implements AttributesMapper {/*** 将单个Attributes转成单个对象* @param attrs* @return* @throws NamingException*/@Overridepublic Object mapFromAttributes(Attributes attrs) throws NamingException {LdapUser user  = new LdapUser();if(attrs.get("uid") != null){user.setUid( attrs.get("uid").get().toString());}if(attrs.get("cn") != null){user.setCn( attrs.get("cn").get().toString());}if(attrs.get("dn") != null){user.setDn( attrs.get("dn").get().toString());}if(attrs.get("sn") != null){user.setSn( attrs.get("sn").get().toString());}if(attrs.get("userPassword") != null){user.setUserPassword(new String((byte[])attrs.get("userPassword").get()));}return user;}
}

LdapUser实体类

package com.ldap.entity;import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;/*** @Author 211145187* @Date 2024/5/22 09:31**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LdapUser {private String uid;private String dn;private String cn;private String sn;private String userPassword;
}

LdapTest测试类

package com.ldap;import com.ldap.entity.LdapUser;
import com.ldap.mapper.LdapUserAttributeMapper;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.test.context.junit4.SpringRunner;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;@SpringBootTest
@RunWith(SpringRunner.class)
public class LdapTest {@Autowiredprivate LdapTemplate ldapTemplate;@Testpublic void listUsers() throws NoSuchAlgorithmException {AndFilter filter = new AndFilter();filter.and(new EqualsFilter("objectClass", "inetOrgPerson"));List<LdapUser> users = ldapTemplate.search("ou=Develop,ou=Hytera", filter.encode(), new LdapUserAttributeMapper());for (LdapUser user: users ) {System.out.println("user: " + user);System.out.println("userPassword:" + user.getUserPassword());System.out.println(verifySHA(user.getUserPassword(), "Eadmin123456"));}//        Assert.assertEquals(123, users.size());}@SuppressWarnings(value = "unchecked")public static boolean verifySHA(String ldappw, String inputpw)throws NoSuchAlgorithmException {// MessageDigest 提供了消息摘要算法,如 MD5 或 SHA,的功能,这里LDAP使用的是SHA-1MessageDigest md = MessageDigest.getInstance("SHA-1");// 取出加密字符if (ldappw.startsWith("{SSHA}")) {ldappw = ldappw.substring(6);} else if (ldappw.startsWith("{SHA}")) {ldappw = ldappw.substring(5);}// 解码BASE64byte[] ldappwbyte = Base64.decode(ldappw);byte[] shacode;byte[] salt;// 前20位是SHA-1加密段,20位后是最初加密时的随机明文if (ldappwbyte.length <= 20) {shacode = ldappwbyte;salt = new byte[0];} else {shacode = new byte[20];salt = new byte[ldappwbyte.length - 20];System.arraycopy(ldappwbyte, 0, shacode, 0, 20);System.arraycopy(ldappwbyte, 20, salt, 0, salt.length);}// 把用户输入的密码添加到摘要计算信息md.update(inputpw.getBytes());// 把随机明文添加到摘要计算信息md.update(salt);// 按SSHA把当前用户密码进行计算byte[] inputpwbyte = md.digest();// 返回校验结果return MessageDigest.isEqual(shacode, inputpwbyte);}}

三、验证结果

在这里插入图片描述
结论:从结果可以看出确实读出来了,而且我也把密码打印出来了。

接下来对打印结果进行讲解

代码

@Testpublic void listUsers() throws NoSuchAlgorithmException {AndFilter filter = new AndFilter();filter.and(new EqualsFilter("objectClass", "inetOrgPerson"));List<LdapUser> users = ldapTemplate.search("ou=Develop,ou=Hytera", filter.encode(), new LdapUserAttributeMapper());for (LdapUser user: users ) {System.out.println("user: " + user);System.out.println("userPassword:" + user.getUserPassword());System.out.println(verifySHA(user.getUserPassword(), "Eadmin123456"));}}

我的需求:假设页面传入了用户名和密码,然后我想从ldap读取所有账户信息,进行账户+密码的比对是否相等,做这么个事儿。

四、易错点讲解

易错点1:java: 无法访问org.springframework.ldap.core.LdapTemplate

完整错误:

java: 无法访问org.springframework.ldap.core.LdapTemplate错误的类文件: /E:/apache-maven-3.6.3/repository/org/springframework/ldap/spring-ldap-core/3.2.3/spring-ldap-core-3.2.3.jar!/org/springframework/ldap/core/LdapTemplate.class类文件具有错误的版本 61.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。

错误原因:引入的依赖版本和Spring版本或者SpringBoot版本不适配(大白话讲:你引入的版本太高了)
我最开始的依赖版本用的是最新的,因为习惯性添加依赖就会莫名添加最新的,结果问题就是它导致的。

<dependency><groupId>org.springframework.ldap</groupId><artifactId>spring-ldap-core</artifactId><version>3.2.3</version>
</dependency>       

解决方案:选择适配的即可,最终可以使用的版本

<dependency><groupId>org.springframework.ldap</groupId><artifactId>spring-ldap-core</artifactId><version>2.4.0</version>
</dependency>

易错点2:java: 无法访问org.springframework.context.ConfigurableApplicationContext

完整错误:

java: 无法访问org.springframework.context.ConfigurableApplicationContext错误的类文件: /E:/apache-maven-3.6.3/repository/org/springframework/spring-context/6.1.7/spring-context-6.1.7.jar!/org/springframework/context/ConfigurableApplicationContext.class类文件具有错误的版本 61.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。

错误原因:引入的依赖版本和Spring版本或者SpringBoot版本不适配(大白话讲:你引入的版本太高了)
我最开始的依赖版本用的是最新的,因为习惯性添加依赖就会莫名添加最新的,结果问题就是它导致的。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-ldap</artifactId><version>3.3.0</version>
</dependency>
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-ldap</artifactId><version>3.3.0</version>
</dependency>

解决方案:选择适配的即可,最终可以使用的版本

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-ldap</artifactId><version>2.6.3</version>
</dependency>
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-ldap</artifactId><version>2.6.3</version>
</dependency>

易错点3:[LDAP: error code 34 - invalid DN]

在这里插入图片描述

完整错误

org.springframework.ldap.InvalidNameException: [LDAP: error code 34 - invalid DN]; nested exception is javax.naming.InvalidNameException: [LDAP: error code 34 - invalid DN]at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:136)at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:363)at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:147)at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:166)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:361)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:332)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:608)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:598)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:486)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:502)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:518)at com.ldap.LdapTest.listUsers(LdapTest.java:31)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: javax.naming.InvalidNameException: [LDAP: error code 34 - invalid DN]at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3095)at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2886)at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2800)at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)at javax.naming.InitialContext.init(InitialContext.java:244)at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:154)at org.springframework.ldap.core.support.LdapContextSource.getDirContextInstance(LdapContextSource.java:42)at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:351)... 41 more

代码长这样:

application.properties

spring.ldap.urls=ldap://10.110.38.162:389
spring.ldap.username=admin
spring.ldap.password=123456
spring.ldap.base=dc=yaobili,dc=com

LdapTest

@Testpublic void listUsers() throws NoSuchAlgorithmException {AndFilter filter = new AndFilter();filter.and(new EqualsFilter("objectClass", "inetOrgPerson"));List<LdapUser> users = ldapTemplate.search("ou=Develop,ou=Hytera", filter.encode(), new LdapUserAttributeMapper());for (LdapUser user: users ) {System.out.println("user: " + user);System.out.println("userPassword:" + user.getUserPassword());System.out.println(verifySHA(user.getUserPassword(), "Eadmin123456"));}}

错误原因:配置文件中spring.ldap.username这里错了,因为我创建了admin管理员账户,但是这里我不知道是输入admin 啊还是输入完整dn

解决方案:此处应该输入完整dn:spring.ldap.username=cn=admin,dc=yaobili,dc=com

易错点4:LDAP: error code 32 - No Such Object

在这里插入图片描述

完整错误

org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Object]; remaining name 'ou=Develop,ou=Hytera,dc=yaobili,dc=com'at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:183)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:380)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:332)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:608)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:598)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:486)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:502)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:518)at com.ldap.LdapTest.listUsers(LdapTest.java:31)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Object]; remaining name 'ou=Develop,ou=Hytera,dc=yaobili,dc=com'at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3179)at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3100)at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2891)at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1846)at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1769)at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341)at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)at org.springframework.ldap.core.LdapTemplate$4.executeSearch(LdapTemplate.java:326)at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:367)... 38 more

错误代码:

application.properties

spring.ldap.urls=ldap://10.110.38.162:389
spring.ldap.username=cn=admin,dc=yaobili,dc=com
spring.ldap.password=123456
spring.ldap.base=ou=Develop,ou=Hytera,dc=yaobili,dc=com

LdapTest

@Testpublic void listUsers() throws NoSuchAlgorithmException {AndFilter filter = new AndFilter();filter.and(new EqualsFilter("objectClass", "inetOrgPerson"));List<LdapUser> users = ldapTemplate.search("ou=Develop,ou=Hytera,dc=yaobili,dc=com", filter.encode(), new LdapUserAttributeMapper());for (LdapUser user: users ) {System.out.println("user: " + user);System.out.println("userPassword:" + user.getUserPassword());System.out.println(verifySHA(user.getUserPassword(), "Eadmin123456"));}}

疑惑:32错误码对应dn设置不对,但是我感觉不出来哪里不对啊,感觉spring.ldap.base和ldapTemplate.search都设置了正确的dn 啊,而且"ou=Develop,ou=Hytera,dc=yaobili,dc=com"这个dn就是我要查询账户所在的完整dn路径啊,不信看图。
在这里插入图片描述

错误原因:spring.ldap.base和ldapTemplate.search是有传递行的(你可以理解为拼接的效果,一因此不能设置一样的否则就乱套了,找不到了)。这易错点特别操蛋,因为根本别人的博客找不到还有这个规则说明,上来就是给你贴配置类文件和代码,然后照抄运行就报错,关键他们也不贴运行结果,我就只能挨个尝试去试错。

解决方案

  • 如果spring.ldap.base设置了spring.ldap.base=“ou=Develop,ou=Hytera,dc=yaobili,dc=com”,那么search方法构面跟的就应该是空字符串“”)
spring.ldap.base=ou=Develop,ou=Hytera,dc=yaobili,dc=com
List<LdapUser> users = ldapTemplate.search("", filter.encode(), new LdapUserAttributeMapper());
  • 如果spring.ldap.base设置了spring.ldap.base=dc=yaobili,dc=com,那么search方法构面跟的就应该是"ou=Develop,ou=Hytera"
spring.ldap.base=dc=yaobili,dc=com
List<LdapUser> users = ldapTemplate.search("ou=Develop,ou=Hytera", filter.encode(), new LdapUserAttributeMapper());

易错点5:配置文件介绍

spring.ldap.urls=ldap://10.110.38.162:389
spring.ldap.username=cn=admin,dc=yaobili,dc=com
spring.ldap.password=123456
spring.ldap.base=dc=yaobili,dc=com
  • spring.ldap.urls配置url,端口分两种:389和3268
    • 端口 389:这是 LDAP(轻量级目录访问协议)的标准端口号。通常,LDAP 服务器使用此端口号来监听 LDAP 请求。大多数基于 LDAP 的应用程序和工具都默认使用此端口号来与 LDAP 服务器通信。
    • 端口 3268:这是全局目录服务接口(Global Catalog Service)的端口号。全局目录是 Active Directory 的一部分,它包含了多个域的数据。端口 3268 允许在全局目录上进行查询,而不仅仅是在单个域中。这使得可以在整个 Active Directory 环境中执行查询操作。
  • spring.ldap.username配置管理元用户名,此处只能输入管理员账户的完整dn,即必须输入cn=admin,dc=yaobili,dc=com才有效,而配置admin会导致无法登陆
  • spring.ldap.password配置密码,这里我试过了,只能配置未加密密码,配置加密密码也会导致无法登陆。
  • spring.ldap.base用于配置 LDAP 查询的基础路径(Base DN)的属性。Base DN 是 LDAP 查询的起始点,它指定了在搜索 LDAP 目录时的起始位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 学习——1. STM32最小系统

这是一个最小系统的测试&#xff0c;LED灯会进行闪烁。选用PC13口&#xff0c;因为STM32F103C8T6 硬件开发板中&#xff0c;这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…

WGCAT工单系统如何配置通知

WGCAT工单系统可以配置邮件通知 只要配置了邮件通知&#xff0c;那么一旦我们账号有新的工单需要处理&#xff0c;就会接受到邮件通知 除了邮件之外&#xff0c;还可以配置其他方式的通知&#xff0c;比如微信钉钉短信等方式&#xff0c;参考如下 https://www.wgstart.com/wgc…

机器学习(五) -- 监督学习(5) -- 线性回归1

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;4&#xff09; -- 集成学习方法 - 随机森林 下篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;5&#xff09; -- 线性回归2 前言 tips&#xff1…

Jmeter例题分析-作业一

作业 作业1概要 本文档是关于执行软件性能测试的详细指南&#xff0c;包括使用JMeter工具进行测试的步骤和要求。 文档分为两个主要部分&#xff1a;性能测试的执行和性能测试报告的编写。 在第一部分中&#xff0c;详细描述了如何使用 JMeter进行性能测试。这包括设置测试环…

力扣刷题---961. 在长度 2N 的数组中找出重复 N 次的元素【简单】

题目描述&#x1f357; 给你一个整数数组 nums &#xff0c;该数组具有以下属性&#xff1a; nums.length 2 * n. nums 包含 n 1 个 不同的 元素 nums 中恰有一个元素重复 n 次 找出并返回重复了 n 次的那个元素。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,3] 输…

leetcode每日一题第八十九天

class Solution { public:int subarraySum(vector<int>& nums, int k) {unordered_map<int,int> mp;mp[0] 1;int count 0,pre 0;for(auto x:nums){pre x;if(mp.find(pre-k) ! mp.end()){count mp[pre-k];}mp[pre];}return count;} };

【LVGL_Linux安装NXP的Gui-Guider】

GUI Guider是恩智浦为LVGL开发了一个上位机GUI设计工具&#xff0c;可以通过拖放控件的方式设计LVGL GUI页面&#xff0c;加速GUI的设计。 虽然他只支持自家芯片&#xff0c;但是应用层我们可以直接拿来用作其他MCU上。 GUI-Guider 下载 NXP官网下载&#xff1a;链接&#xff1…

无界鼠标与键盘,如何轻松控制多台电脑

简介 在软件开发领域&#xff0c;高效地管理多台电脑是至关重要的。Mouse without Borders软件为开发人员提供了一种便捷的解决方案&#xff0c;使他们能够轻松地在多台电脑之间共享鼠标和键盘。不仅如此&#xff0c;Mouse without Borders还提供了许多高级功能&#xff0c;如…

Android 12系统源码_多窗口模式(二)系统实现分屏的功能原理

前言 上一篇我们具体分析了系统处于多窗口模式下&#xff0c;Android应用和多窗口模式相关方法的调用顺序&#xff0c;对于应用如何适配多窗口模式有了一个初步的认识&#xff0c;本篇文章我们将会结合Android12系统源码&#xff0c;具体来梳理一下系统是如何触发多窗口分屏模…

HarmonyOS 鸿蒙应用开发 - 多态样式 stateStyles

前言&#xff1a;Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式&#xff0c;类似于css伪类&#xff0c;但语法不同。 ArkUI提供以下四种状态&#xff1a; focused&#xff1a;获焦态。normal&…

就业班 第三阶段(ELK) 2401--5.20 day1 ELK 企业实战 ES+head+kibana+logstash部署(最大集群)

ELKkafkafilebeat企业内部日志分析系统 1、组件介绍 1、Elasticsearch&#xff1a; 是一个基于Lucene的搜索服务器。提供搜集、分析、存储数据三大功能。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff…

Git 仓库中 -- 代码冲突产生、定位、解决的流程

目录 前置知识1 工具环境2 冲突的产生2.1 仓库中的源代码2.2 人员 A 首先更改代码2.3 人员 B 更改代码&#xff0c;产生冲突2.3.1 第一次错误提示&#xff1a;2.3.2 第二次错误提示&#xff1a; 3 查看冲突4 手动解决冲突4.1 方式一4.2 方式二&#xff08;tortoisegit&#xff…

【Linux网络】端口及UDP协议

文章目录 1.再看四层2.端口号2.1引入linux端口号和进程pid的区别端口号是如何生成的传输层有了pid还设置端口号端口号划分 2.2问题2.3netstat 3.UDP协议3.0每学一个协议 都要讨论一下问题3.1UDP协议3.2谈udp/tcp实际上是在讨论什么&#xff1f; 1.再看四层 2.端口号 端口号(Po…

基于Android studio 使用SQLite数据库完成登录注册功能——保姆级教程

&#x1f345;文章末尾有获取完整项目源码方式&#x1f345; 点击快捷传送地址&#xff1a; 保姆级教学——制作登陆注册功能页面 目录 一、准备工作 二、创建相关文件 三、页面布局 四、DabaHelper帮助类的编写 五、RegisterActivity注册页面 六、LoginActivity登录页面…

代码随想录算法训练营第三十七天|435. 无重叠区间、763.划分字母区间、56. 合并区间、738.单调递增的数字、968.监控二叉树

435. 无重叠区间 文档讲解&#xff1a;代码随想录 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 本道题与上个题目相似&#xff0c;都是求重叠区间 统计重叠区间的个数&#xff0c;减去重叠区间的个数就是无重叠区间了 主要就是为了让区间尽可能的重叠。&a…

微信小程序源码-基于Java后端的会议发布与预约系统毕业设计(附源码+演示录像+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设…

Java的结构与运行机制

1. JDK JRE JVM三者的区别 JDK(Java Development Kit)&#xff1a;Java开发工具包 JDK包含JRE&#xff0c;还包括其他例如&#xff1a;编译器(javac)、javadoc、jar等&#xff0c;JDK是能够创建和编译程序的。 JRE(Java runtime environment)&#xff1a;Java运行环境 JRE是运…

手把手一起学习Python NumPy

NumPy 是用于处理数组的 python 库&#xff0c;NumPy 中的数组对象称为 ndarray&#xff0c;它提供了许多支持函数&#xff0c;使得利用 ndarray 非常容易。Numpy官方网址 NumPy 安装 使用pip安装NumPy 模块&#xff1a; pip install numpyNumPy 入门 创建numpy数组&#x…

基于Python的k-means聚类分析算法的实现与应用,可以用在电商评论、招聘信息等各个领域的文本聚类及指标聚类,效果很好

以微博考研话题为例 思路步骤&#xff1a; 数据清洗&#xff1a; 使用pandas读取数据文件&#xff0c;并进行数据清洗和预处理&#xff0c;包括去除重复值、数据替换等。 数据处理实现&#xff1a; 数据处理的过程如下&#xff1a; 数据清洗主要包括去重和数据转换两个步骤…

Magisk + JustTrustMe 安装配置

操作步骤&#xff1a; 安装 Magisk 面具&#xff08;手机root&#xff09;在面具中刷入 LSPosed框架安装 JustTrustMe在LSPosed框架中配置并启动 JustTrustMe 一&#xff0c;Magisk面具 请根据自己手机的机型去root并安装面具&#xff0c;参考链接&#xff1a; https://www…