Spring Security + LDAP 总是返回 BadCredentialsException

Posted

技术标签:

【中文标题】Spring Security + LDAP 总是返回 BadCredentialsException【英文标题】:Spring Security + LDAP always returns BadCredentialsException 【发布时间】:2015-11-12 22:39:21 【问题描述】:

我一直在尝试配置 Spring Security 以使用 LDAP,但收效甚微。

我有以下配置bean:

@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() 

    ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("go.com.mt", "LDAP://CORPORATE.INTRA");
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setUserDetailsContextMapper(userDetailsContextMapper());
    return provider;


@Bean
public UserDetailsContextMapper userDetailsContextMapper() 
    UserDetailsContextMapper contextMapper = new AttributesLDAPUserDetailsContextMapper();
    return contextMapper;


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

我尝试按照此处关于堆栈溢出的许多答案的建议创建自定义映射器,将每个权限设置为 ROLE_USER

public class AttributesLDAPUserDetailsContextMapper implements UserDetailsContextMapper 
    @Override
    public UserDetails mapUserFromContext(DirContextOperations dirContextOperations, String username, Collection<? extends GrantedAuthority> authority) 
        List<GrantedAuthority> mappedAuthorities = new ArrayList<GrantedAuthority>();
        for (GrantedAuthority granted : authority) 
            if (true) 
                mappedAuthorities.add(() -> "ROLE_USER");
             else if(granted.getAuthority().equalsIgnoreCase("MY ADMIN GROUP")) 
                mappedAuthorities.add(() -> "ROLE_ADMIN");
            
        
        return new User(username, "", mappedAuthorities);
    

    @Override
    public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) 

    

当我尝试使用现有用户和错误密码进行身份验证时,我收到以下消息:

[apr-8080-exec-6] ctiveDirectoryLdapAuthenticationProvider : Active Directory authentication failed: Supplied password was invalid
[apr-8080-exec-6] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Thu Aug 20 07:31:59 CEST 2015, principal=samantha.catania, type=AUTHENTICATION_FAILURE, data=type=org.springframework.security.authentication.BadCredentialsException, message=Bad credentials]

表示活动目录正在正常工作,但是当我尝试使用正确的凭据进行身份验证时,我收到以下消息:

[pr-8080-exec-10] o.s.s.ldap.SpringSecurityLdapTemplate    : Ignoring PartialResultException
[pr-8080-exec-10] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Thu Aug 20 07:32:05 CEST 2015, principal=samantha.catania, type=AUTHENTICATION_FAILURE, data=type=org.springframework.security.authentication.BadCredentialsException, message=Bad credentials]

有什么办法可以解决这个问题吗?

【问题讨论】:

检查是否收藏 extends GrantedAuthority> 权限为空或为空。让我知道。 我在两种映射器方法中都添加了日志,但它们从未被打印出来。我还添加了断点,它永远不会停在那里@.@ 在哪里以及使用哪些映射器方法.. 你能更精确一点... /跨度> 在我更新并设置了 DN 之后,映射器开始被调用。似乎错误是在映射发生之前发生的 【参考方案1】:

问题似乎是因为ActiveDirectoryLdapAuthenticationProvider 正在“猜测”使用域的 DN。将spring-security-ldap 更新到最新版本,使new constructor with 3 parameters 可用,其中最后一个允许您指定 DN。之后,映射器开始被成功调用并通过身份验证。

我要感谢所有做出贡献的人:)

【讨论】:

【参考方案2】:

尝试使用将 java 环境属性“java.naming.referral”设置为“follow”(在启动时的代码中,或通过 JVM -Djava.naming.referral=follow 的参数。

您是否获得堆栈跟踪,或者您是否可以打印 BadCredentialsException?

这与我遇到的 AD 问题非常相似,问题在于 AD 如何处理引荐,这会在数据检索期间产生错误。

根据您发布的内容,我预计 ActiveDirectoryLdapAuthenticationProvider.java line 323 中会生成异常,这将指向相同的问题。

【讨论】:

以上是关于Spring Security + LDAP 总是返回 BadCredentialsException的主要内容,如果未能解决你的问题,请参考以下文章

Spring 3,Spring Security,LDAP,如何向 LDAP 添加角色?

Spring MVC + Spring Security + LDAP

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

Grails,Spring Security LDAP 插件

Spring Security和LDAP身份验证

如何将 Spring Security 从 ldap 更改为 ldap starttls