Reputation: 1079
I am working on a spring boot maven project to authenticate users having username and password. The microservice needs to return true/false if user is authenticated.
The 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;
}
}
I am calling the following method by passing username and password
public Authentication signin(String username, String password) throws Exception{
Authentication auth = new UsernamePasswordAuthenticationToken("[email protected]", "password");
return authenticationManager.authenticate(auth); // this line gives Bad Credential error
}
I am getting the following error when calling method 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)
Caused by: org.springframework.security.ldap.authentication.ad.ActiveDirectoryAuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580
I went through the following links: javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]
Active Directory Authentication using Spring Security 3.2, Spring Ldap 2.0 and JavaConfig
Based on above links I have tried setAuthoritiesMapper and passed NullAuthoritiesMapper as I don't have any authorities to map.
adProvider.setAuthoritiesMapper(new NullAuthoritiesMapper());
I tried to make changes to userDNPattern = "CN=pan,OU=Users,OU=UCV,DC=org,DC=abc,DC=in";
but it didn't work. CN= pan is my username
I am able to access the Apache Active Directory with above url, domain and userDnPattern and password. Do I need to encode the password?
Upvotes: 2
Views: 5430
Reputation: 40928
This may not be the only problem, but this is certainly part of it:
adProvider.setSearchFilter(userDNPattern);
That method takes the LDAP query to find the user, not a DN. The documentation for setSearchFilter()
says that the default is this:
(&(objectClass=user)(userPrincipalName={0}))
That will take the username you give it, and find the user with that userPrincipalName
("[email protected]" format).
If that's what you want, then you don't need to call setSearchFilter()
at all.
If you want users to be able to login using just the username (sAMAccountName
), then you can use this:
adProvider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
Update: I think you have a couple other problems too:
private String url = "ldaps://org.abc.in:3387";
private String domain = "org.abc.in";
First, ldaps://
isn't actually valid. Just use ldap://
. If the specified port uses SSL, then it will do the SSL handshake.
Also, you're setting the domain to org.abc.in
, but when you're logging in, you're using @abc.in
. The domain
you specify is appended to the username you specify for login, so it's trying to log you in with [email protected]@org.abc.in
, which of course won't work. You are better off just setting the domain
to null
so it doesn't try to append anything later. But that would mean your users would need to login with the [email protected]
format.
Upvotes: 3
Reputation: 4475
your domain is "org.abc.in". change "[email protected]" to "pan", ActiveDirectoryLdapAuthenticationProvider will automatically add your domain to it as you already specified it during it's creation ("org.abc.in").
Upvotes: 2