java链接ldap报错LDAP: error code 34 - invalid DN
ldap配置如下
dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcSuffix
olcSuffix:dc=yaobili,dc=com
dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcRootDN
olcRootDN:cn=admin,dc=yaobili,dc=com
dn:olcDatabase={2}hdb,cn=config
changetype:modify
replace:olcRootPW
olcRootPW:{SSHA}IHveDAPJPxUFiKF17cVPg3Humkh1GjJj
dn:olcDatabase={2}hdb,cn=config
changetype:modify
add:olcAccess
olcAccess:{0}to attrs=userPassword,shadowLastChange by dn="cn=admin,dc=yaobili,dc=com" write by anonymous auth by self write by * none
olcAccess:{1}to dn.base="" by * read
olcAccess:{2}to * by dn="cn=admin,dc=yaobili,dc=com" write by * read
dn:ou=Develop,ou=Hytera,dc=yaobili,dc=com
objectClass:organizationalUnit
ou:Develop
创建组织架构
dn:ou=Hytera,dc=yaobili,dc=com
objectClass:organizationalUnit
ou:Hytera
dn: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=com
下面是我的代码
application.properties
server.port=8020
spring.ldap.urls=ldap://10.110.38.162:389
spring.ldap.username=admin
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;
/**
* 继承LdapContextSource重写getAnonymousEnv方法来加载,
* 使连接ldap时用SSL连接(由于修改AD密码时必须使用SSL连接)
*/
// public class SsldapContextSource extends LdapContextSource {
// public Hashtable<String, Object> getAnonymousEnv() {
// System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
// Hashtable<String, Object> anonymousEnv = super.getAnonymousEnv();
// anonymousEnv.put("java.naming.security.protocol", "ssl");
// anonymousEnv.put("java.naming.ldap.factory.socket", CustomSslSocketFactory.class.getName());
// anonymousEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// return anonymousEnv;
// }
// }
@Bean
public 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;
// SsldapContextSource ldapContextSource = new SsldapContextSource();
// ldapContextSource.setBase(base);
// ldapContextSource.setUrl(dbUrl);
// ldapContextSource.setUserDn(username);
// ldapContextSource.setPassword(password);
// ldapContextSource.setPooled(false);
// ldapContextSource.setReferral("follow");
// ldapContextSource.afterPropertiesSet();
// return ldapContextSource;
}
@Bean
public LdapTemplate ldapTemplate(LdapContextSource contextSource) {
if (Objects.isNull(contextSource)) {
throw new RuntimeException("ldap contextSource error");
}
if (null == ldapTemplate) {
ldapTemplate = new LdapTemplate(contextSource);
}
return ldapTemplate;
}
}
测试类
@SpringBootTest
@RunWith(SpringRunner.class)
public class LdapTest {
@Autowired
private LdapTemplate ldapTemplate;
@Test
public void listUsers(){
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);
}
// Assert.assertEquals(123, users.size());
}
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
*/
public 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("username") != null){
user.setUsername( attrs.get("username").get().toString());
}
if(attrs.get("userPassword") != null){
user.setUserPassword( attrs.get("userPassword").get().toString());
}
return user;
}
}
我在整体解释下:
我创建了admin管理账户,然后我又创建了2个账户dn: cn=ldapUser1,ou=Develop,ou=Hytera,dc=yaobili,dc=com,所属的组委ou=Develop,ou=Hytera,dc=yaobili,dc=com
我现在需求是java链接ldap,然后读取组Develop(ou=Develop,ou=Hytera,dc=yaobili,dc=com)下面的所有账户,即想把ldapUser1和ldapUser2信息全部读取出来