Java 如何在Spring Security中从LDAP获取其他用户属性?
我目前正在尝试开发一个Spring引导应用程序,其目的是管理LDAP目录中的用户条目 LDAP登录已经工作;查找用户所属的组也是如此 此外,我想用该用户的一些LDAP属性填充Spring SecurityJava 如何在Spring Security中从LDAP获取其他用户属性?,java,spring-security,spring-boot,spring-ldap,spring-security-ldap,Java,Spring Security,Spring Boot,Spring Ldap,Spring Security Ldap,我目前正在尝试开发一个Spring引导应用程序,其目的是管理LDAP目录中的用户条目 LDAP登录已经工作;查找用户所属的组也是如此 此外,我想用该用户的一些LDAP属性填充Spring SecurityPrincipal对象。我已经读了好几篇关于SO的帖子以及Spring的官方文档,但根本无法实现这一点 这是我目前的代码: 类AuthenticationConfiguration @Configuration class AuthenticationConfiguration extends
Principal
对象。我已经读了好几篇关于SO的帖子以及Spring的官方文档,但根本无法实现这一点
这是我目前的代码:
类AuthenticationConfiguration
@Configuration
class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
private String ldapUrl = "ldap://127.0.0.1:10389/dc=corp,dc=org";
private String bindUser = "cn=spring,ou=users,dc=corp,dc=org";
private String bindPW = "<password>";
private String groupSearchBase = "ou=groups";
private String groupSearchFilter = "(member={0})";
private String userDnPattern = "uid={0},ou=users";
private Log log = LogFactory.getLog(this.getClass());
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapUrl);
contextSource.setUserDn(bindUser);
contextSource.setPassword(bindPW);
contextSource.afterPropertiesSet();
log.info(contextSource.getReadOnlyContext().getAttributes("uid=testuser,ou=users")); // returns all LDAP attributes from that user
DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);
populator.setGroupSearchFilter(groupSearchFilter);
populator.setSearchSubtree(true);
populator.setIgnorePartialResultException(true);
auth
.ldapAuthentication()
.ldapAuthoritiesPopulator(populator)
.contextSource(contextSource)
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns(userDnPattern)
;
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new CustomUserDetailsContextMapper();
}
}
现在,当您查看AuthenticationConfiguration
中的第一条日志语句时,Spring实际上会将整个用户对象打印到stdout,正确显示用户的所有LDAP属性:
{displayname=displayname:Test用户,givenname=givenname:Test,objectclass=objectclass:posixAccount,top[…]}
但是,myCustomUserDetailsContextMapper
类中的日志语句没有。虽然第一个正确显示登录用户的DN,但第二个仅显示0,即ctx似乎不包含当前用户的任何属性。
我还尝试通过ctx.getAttribute(“属性”)
、ctx.getStringAttribute(“属性”)
或ctx.getObjectAttribute(“属性”)
直接查询属性,但没有成功
如何从mapUserFromContext
方法中访问LDAP属性?
我真的没有主意了,所以任何帮助都将不胜感激:-)解决了它。问题不在应用程序代码中,而在LDAP配置中 因为我使用的是默认的BindAuthenticator,所以Spring Security尝试使用登录表单中指定的用户绑定到LDAP。不幸的是,ou=users下的所有用户在LDAP配置中只有
search
权限。将search
更改为read
(参见第8.2.3点)为我解决了这个问题
请注意,登录/绑定本身仍然成功(因为
auth
权限是search
的一个子集),但任何属性检索都失败,因为这需要读取
权限。对于@mpm示例:
希望这对某人有帮助。这是我的UserDetails
public class CustomUserDetails implements LdapUserDetails {
private String iin;
private String colvirId;
private LdapUserDetails details;
public CustomUserDetails(LdapUserDetails details) {
this.details = details;
}
public String getIin() {
return iin;
}
public void setIin(String iin) {
this.iin = iin;
}
public String getColvirId() {
return colvirId;
}
public void setColvirId(String colvirId) {
this.colvirId = colvirId;
}
@Override
public String getDn() {
return details.getDn();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return details.getAuthorities();
}
@Override
public String getPassword() {
return details.getPassword();
}
@Override
public String getUsername() {
return details.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return details.isAccountNonExpired();
}
@Override
public boolean isAccountNonLocked() {
return details.isAccountNonLocked();
}
@Override
public boolean isCredentialsNonExpired() {
return details.isCredentialsNonExpired();
}
@Override
public boolean isEnabled() {
return details.isEnabled();
}
}
public类CustomUserDetails实现LdapUserDetails{
私有字符串iin;
私有字符串colvirId;
私人LdapUserDetails;
公共CustomUserDetails(LdapUserDetails){
this.details=详细信息;
}
公共字符串getIin(){
返回iin;
}
公共无效设置iin(字符串iin){
这个。iin=iin;
}
公共字符串getColvirId(){
返回colvirId;
}
public void setColvirId(字符串colvirId){
this.colvirId=colvirId;
}
@凌驾
公共字符串getDn(){
返回details.getDn();
}
@凌驾
公共收藏
public class CustomUserDetails implements LdapUserDetails {
private String iin;
private String colvirId;
private LdapUserDetails details;
public CustomUserDetails(LdapUserDetails details) {
this.details = details;
}
public String getIin() {
return iin;
}
public void setIin(String iin) {
this.iin = iin;
}
public String getColvirId() {
return colvirId;
}
public void setColvirId(String colvirId) {
this.colvirId = colvirId;
}
@Override
public String getDn() {
return details.getDn();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return details.getAuthorities();
}
@Override
public String getPassword() {
return details.getPassword();
}
@Override
public String getUsername() {
return details.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return details.isAccountNonExpired();
}
@Override
public boolean isAccountNonLocked() {
return details.isAccountNonLocked();
}
@Override
public boolean isCredentialsNonExpired() {
return details.isCredentialsNonExpired();
}
@Override
public boolean isEnabled() {
return details.isEnabled();
}
}