当域与userPrincipalName结尾不匹配时,LDAP AD Spring Security身份验证失败

问题描述 投票:0回答:1

我正在使用ActiveDirectoryLdapAuthenticationProvider对AD服务器进行身份验证。它在大多数环境下都可以正常工作,但是域名与单个用户userPrincipalName的结尾不同时会出现问题。

我已经设置了以下属性:

xxx.api.auth.ad.domain:foo.bar.com
xxx.api.auth.ad.url:ldaps://yyy.foo.bar.com:636

并且用户将userPrincipalName设置为[email protected]。注意与域名的区别

然后在我的LoginService中,我有这个:

private AuthResultDto loginAD(LoginDto login) {

    String adDomain = env.getProperty("xxx.api.auth.ad.domain");
    String adUrl = env.getProperty("xxx.api.auth.ad.url");

    ActiveDirectoryLdapAuthenticationProvider provider = 
            new ActiveDirectoryLdapAuthenticationProvider(adDomain, adUrl);
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setUserDetailsContextMapper(new InetOrgPersonContextMapper());

    Authentication auth = provider
            .authenticate(new UsernamePasswordAuthenticationToken(login.getEmail(), login.getPassword()));

    if (!auth.isAuthenticated())
        throw new CustomMessageException("Invalid Login");
...
}

在这种情况下,身份验证失败,并显示消息Active Directory authentication failed: Supplied password was invalid

spring-ldap-core:2.3.2.RELEASEspring-security-ldap:5.0.3.RELEASE

spring-security spring-ldap spring-security-ldap
1个回答
0
投票

问题似乎是createBindPrincipal()内的ActiveDirectoryLdapAuthenticationProvider检查username是否以domain结尾,否则检查为appends it。这导致用户名变为[email protected]@foo.bar.com

[很遗憾,ActiveDirectoryLdapAuthenticationProvider是最终的,因此无法覆盖它。我们采用的解决方案是不传递domain,而是传递rootDN(由复制ActiveDirectoryLdapAuthenticationProvider中的代码构成)

private AuthResultDto loginAD(LoginDto login) {

    String adDomain = env.getProperty("xxx.api.auth.ad.domain");
    String adUrl = env.getProperty("xxx.api.auth.ad.url");

    ActiveDirectoryLdapAuthenticationProvider provider = 
            new ActiveDirectoryLdapAuthenticationProvider(null, adUrl, rootDnFromDomain(adDomain));
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setUserDetailsContextMapper(new InetOrgPersonContextMapper());

    Authentication auth = provider
            .authenticate(new UsernamePasswordAuthenticationToken(login.getEmail(), login.getPassword()));

    if (!auth.isAuthenticated())
        throw new CustomMessageException("Invalid Login");
...
}

// copied from ActiveDirectoryLdapAuthenticationProvider
private String rootDnFromDomain(String domain) {
    String[] tokens = StringUtils.tokenizeToStringArray(domain, ".");
    StringBuilder root = new StringBuilder();

    for (String token : tokens) {
        if (root.length() > 0) {
            root.append(',');
        }
        root.append("dc=").append(token);
    }

    return root.toString();
}
© www.soinside.com 2019 - 2024. All rights reserved.