Java 如何在Spring Security中从LDAP获取其他用户属性?

Java 如何在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

我目前正在尝试开发一个Spring引导应用程序,其目的是管理LDAP目录中的用户条目

LDAP登录已经工作;查找用户所属的组也是如此

此外,我想用该用户的一些LDAP属性填充Spring Security
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[…]}

但是,my
CustomUserDetailsContextMapper
类中的日志语句没有。虽然第一个正确显示登录用户的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();
    }
}