通过spring security进行的Active Directory身份验证会返回由LDAP引起的有效用户的错误凭据:错误代码49
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过spring security进行的Active Directory身份验证会返回由LDAP引起的有效用户的错误凭据:错误代码49相关的知识,希望对你有一定的参考价值。
我正在开发一个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
基于以上链接,我尝试了setAuthoritiesMapper并传递了NullAuthoritiesMapper,因为我没有任何权限可以映射。
adProvider.setAuthoritiesMapper(new NullAuthoritiesMapper());
我试图改变userDNPattern = "CN=pan,OU=Users,OU=UCV,DC=org,DC=abc,DC=in";
but它没有用。 CN = pan是我的用户名
我可以使用上面的url,domain和userDnPattern以及密码访问Apache Active Directory。我需要对密码进行编码吗?
您的域名是“org.abc.in”。将“pan@abc.in”更改为“pan”,ActiveDirectoryLdapAuthenticationProvider会自动将您的域添加到它中,因为您在创建它时已经指定了它(“org.abc.in”)。
这可能不是唯一的问题,但这肯定是其中的一部分:
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
格式登录。
以上是关于通过spring security进行的Active Directory身份验证会返回由LDAP引起的有效用户的错误凭据:错误代码49的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 通过 post 对用户进行身份验证
Spring Security - 通过 URL 进行身份验证
防止 Spring Security 通过下一个身份验证提供程序对具有 BadCredentialException 的用户进行身份验证
用户必须先通过 Spring Security 进行身份验证,然后才能完成授权