Spring Security LDAP 身份验证抛出 NO_ATTRIBUTE_OR_VAL 错误

Posted

技术标签:

【中文标题】Spring Security LDAP 身份验证抛出 NO_ATTRIBUTE_OR_VAL 错误【英文标题】:Spring Security LDAP Authentication throws NO_ATTRIBUTE_OR_VAL error 【发布时间】:2018-10-04 18:46:04 【问题描述】:

在遵循 spring.io 指南时,我无法针对真正的 LDAP/AD 进行身份验证:https://spring.io/guides/gs/authenticating-ldap/

当对 real AD/LADP 进行身份验证时遇到的问题是:

org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 16 - 00002080: AtrErr: DSID-03080155, #1:
    0: 00002080: DSID-03080155, problem 1001 (NO_ATTRIBUTE_OR_VAL), data 0, Att 23 (userPassword)
]; nested exception is javax.naming.directory.NoSuchAttributeException: [LDAP: error code 16 - 00002080: AtrErr: DSID-03080155, #1:
0: 00002080: DSID-03080155, problem 1001 (NO_ATTRIBUTE_OR_VAL), data 0, Att 23 (userPassword)
]; remaining name 'CN=olahell,OU=Consultants,OU=Production,OU=Company' 

以下是我的 java auth 配置:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.ldapAuthentication()
                .userSearchFilter("(&(objectClass=user)(sAMAccountName=0))")
                .contextSource()
                .url("ldap://company-dc02.company.local:389/dc=company,dc=local")
                .managerDn("CN=olahell,OU=Consultants,OU=Production,OU=Company,DC=company,DC=local")
                .managerPassword("myPassword")
            .and()
                .passwordCompare()
                .passwordEncoder(new LdapShaPasswordEncoder())
                .passwordAttribute("userPassword");

【问题讨论】:

【参考方案1】:

我需要做的是使用BindAuthenticator,LDAP应该配置如下:

@Bean
public AuthenticationProvider ldapAuthenticationProvider() throws Exception 
        String ldapServerUrl = "ldap://company-dc02.bergsala.local:389/dc=company,dc=local";
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapServerUrl);
        String ldapManagerDn = "CN=olahell,OU=Consultants,OU=Production,OU=Company,DC=company,DC=local";
        contextSource.setUserDn(ldapManagerDn);
        String ldapManagerPassword = "myPassword";
        contextSource.setPassword(ldapManagerPassword);
        contextSource.setReferral("follow");
        contextSource.afterPropertiesSet();
        LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch("", "(&(objectClass=user)(sAMAccountName=0))", contextSource);
        BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
        bindAuthenticator.setUserSearch(ldapUserSearch);
        LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, new EmsLdapAuthoritiesPopulator(contextSource, ""));
        return ldapAuthenticationProvider;
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.authenticationProvider(ldapAuthenticationProvider());
    

注意:EmsLdapAuthoritiesPopulator 扩展 DefaultLdapAuthoritiesPopulator 并覆盖 #getAdditionalRoles 以使我能够为用户设置额外的角色。

【讨论】:

以上是关于Spring Security LDAP 身份验证抛出 NO_ATTRIBUTE_OR_VAL 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring security 2.0.3 的 LDAP 身份验证

使用 Spring Boot/Spring Security 对 LDAP 进行证书身份验证

使用 Spring Security 3 进行 LDAP 身份验证

使用 spring security ldap 禁用基本身份验证

使用 Spring Security 配置自定义 LDAP 身份验证提供程序

如何使用 spring-security-core-ldap 插件在 grails 中实现 LDAP 身份验证?