Spring LdapRepository returns 没有结果,而 Spring 安全有效
Spring LdapRepository returns no results while Spring Security works
我的问题
我正在使用 LdapRepository 从 Ldap 服务器获取用户信息。此 Ldap 服务器也由 Spring 安全部门查询以验证用户。
我的问题是,Spring 安全性能够找到并识别用户,而我无法使用相同的 LdapContextSource 通过我的 LdapRepository 找到用户。以任何方式查询 LdapRepository 都不会 return 结果(null
或空列表)。
我试过的
- 直接使用 ldapsearch 工具 - Works
- 使用
LdapQuery
而不是 findByUsername
方法 - 不起作用
- 测试方法如
findAll()
(CrudRepository
) - Returns 一个空列表
- 正在尝试从
spring-ldap
获取日志 - Seems to be impossible?
使用的 ldapsearch 命令:ldapsearch -x -H ldaps://<domain> -b o=<org> uid=<uid>
查看 Wireshark 中的流量(使用 ldap
而不是 ldaps
)看起来 LdapRepository 根本没有执行任何查询,连接只是打开和关闭,结果为 0。
相关代码
LdapContextSource的配置
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldaps://<domain>");
contextSource.setBase("o=<org>");
return contextSource;
}
安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final LdapContextSource ldapContext;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, LdapContextSource ldapContext) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.ldapContext = ldapContext;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.ldapAuthentication()
.contextSource(ldapContext)
.userSearchFilter("(uid={0})");
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
}
用户存储库
@Repository
public interface UserRepository extends LdapRepository<User> {
User findByUsername(String username);
List<User> findByUsernameLikeIgnoreCase(String username);
}
用户
@Entry(
objectClasses = {})
public class User {
@Id
private Name id;
@Attribute(name = "uid", readonly = true)
private String username;
public Name getId() {
return id;
}
public String getUsername() {
return username;
}
}
我找到了解决方案。
Spring 似乎假设 User
的 objectClass
是 User
,如果没有明确设置的话。设置正确的 objectClasses 可以解决这个问题。
我的问题
我正在使用 LdapRepository 从 Ldap 服务器获取用户信息。此 Ldap 服务器也由 Spring 安全部门查询以验证用户。
我的问题是,Spring 安全性能够找到并识别用户,而我无法使用相同的 LdapContextSource 通过我的 LdapRepository 找到用户。以任何方式查询 LdapRepository 都不会 return 结果(null
或空列表)。
我试过的
- 直接使用 ldapsearch 工具 - Works
- 使用
LdapQuery
而不是findByUsername
方法 - 不起作用 - 测试方法如
findAll()
(CrudRepository
) - Returns 一个空列表 - 正在尝试从
spring-ldap
获取日志 - Seems to be impossible?
使用的 ldapsearch 命令:ldapsearch -x -H ldaps://<domain> -b o=<org> uid=<uid>
查看 Wireshark 中的流量(使用 ldap
而不是 ldaps
)看起来 LdapRepository 根本没有执行任何查询,连接只是打开和关闭,结果为 0。
相关代码
LdapContextSource的配置
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldaps://<domain>");
contextSource.setBase("o=<org>");
return contextSource;
}
安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final LdapContextSource ldapContext;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, LdapContextSource ldapContext) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.ldapContext = ldapContext;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.ldapAuthentication()
.contextSource(ldapContext)
.userSearchFilter("(uid={0})");
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
}
用户存储库
@Repository
public interface UserRepository extends LdapRepository<User> {
User findByUsername(String username);
List<User> findByUsernameLikeIgnoreCase(String username);
}
用户
@Entry(
objectClasses = {})
public class User {
@Id
private Name id;
@Attribute(name = "uid", readonly = true)
private String username;
public Name getId() {
return id;
}
public String getUsername() {
return username;
}
}
我找到了解决方案。
Spring 似乎假设 User
的 objectClass
是 User
,如果没有明确设置的话。设置正确的 objectClasses 可以解决这个问题。