通过Spring Security进行的Active Directory身份验证会由于LDAP而为有效用户返回错误的凭据:错误代码49

时间:2018-12-20 18:22:50

标签: spring-boot spring-security active-directory ldap

我正在从事Spring Boot Maven项目,以验证具有用户名和密码的用户。如果用户通过身份验证,则微服务需要返回true / false。

SecurityConfiguration.java

package com.app.config;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);

    private String url = "ldaps://org.abc.in:3387";
    private String domain = "org.abc.in";
    private String userDNPattern = "CN=pan,OU=Users,OU=UCV,DC=org,DC=abc,DC=in";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                        .authorizeRequests().antMatchers("/", "logout").permitAll();

    }


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

        }

     @Bean
        public AuthenticationManager authenticationManager() {
         return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
        }

     @Bean
        public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {

            ActiveDirectoryLdapAuthenticationProvider adProvider = new ActiveDirectoryLdapAuthenticationProvider(domain, url);
            adProvider.setConvertSubErrorCodesToExceptions(true);
            adProvider.setUseAuthenticationRequestCredentials(true);
            //adProvider.setAuthoritiesMapper(new NullAuthoritiesMapper());
            return adProvider;
        }

}

我通过传递用户名和密码来调用以下方法

public Authentication signin(String username, String password) throws Exception{
        Authentication auth = new UsernamePasswordAuthenticationToken("pan@abc.in", "password");
        return authenticationManager.authenticate(auth); // this line gives Bad Credential error
    }

调用方法authenticationManager.authenticate(auth)时出现以下错误

ctiveDirectoryLdapAuthenticationProvider : Active Directory authentication failed: Supplied password was invalid
org.springframework.security.authentication.BadCredentialsException: Bad credentials
    at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.badCredentials(ActiveDirectoryLdapAuthenticationProvider.java:308)

由以下原因引起:org.springframework.security.ldap.authentication.ad.ActiveDirectoryAuthenticationException:[LDAP:错误代码49-80090308:LdapErr:DSID-0C09042F,注释:AcceptSecurityContext错误,数据52e,v2580

我通过以下链接: javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]

Active Directory Authentication using Spring Security 3.2, Spring Ldap 2.0 and JavaConfig

LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1

基于上面的链接,我尝试了setAuthoritiesMapper并通过了NullAuthoritiesMapper,因为我没有要映射的权限。

adProvider.setAuthoritiesMapper(new NullAuthoritiesMapper());

我试图对userDNPattern = "CN=pan,OU=Users,OU=UCV,DC=org,DC=abc,DC=in";进行更改,但是没有用。 CN = pan是我的用户名

我能够使用上述url,domain和userDnPattern和密码访问Apache Active Directory。我需要对密码进行编码吗?

2 个答案:

答案 0 :(得分:1)

这可能不是唯一的问题,但这当然是其中的一部分:

adProvider.setSearchFilter(userDNPattern);

该方法采用LDAP查询来查找用户,而不是DN。 documentation for setSearchFilter()表示默认值为:

(&(objectClass=user)(userPrincipalName={0}))

这将使用您提供的用户名,并找到具有userPrincipalName(“ username@domain.com”格式)的用户。

如果这就是您想要的,那么您根本不需要致电setSearchFilter()

如果您希望用户仅使用用户名(sAMAccountName)进行登录,则可以使用以下名称:

adProvider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");

更新:我认为您还有其他一些问题:

private String url = "ldaps://org.abc.in:3387";
private String domain = "org.abc.in";

首先,ldaps://实际上无效。只需使用ldap://。如果指定的端口使用SSL,则它将进行SSL握手。

此外,您将域设置为org.abc.in,但登录时使用的是@abc.in。您指定的domain会附加到您指定用于登录的用户名之后,因此它尝试使用pan@abc.in@org.abc.in登录,这当然是行不通的。最好将domain设置为null,这样以后就不再尝试添加任何内容了。但这意味着您的用户将需要使用username@abc.in格式登录。

答案 1 :(得分:1)

您的域是“ org.abc.in”。 将“ pan@abc.in”更改为“ pan”,ActiveDirectoryLdapAuthenticationProvider会自动将您的域添加到该域中,就像您在创建域时指定的那样(“ org.abc.in”)。