authenticationspring-bootspring-securityspring-ldapspring-security-ldap

Spring boot ldap security


Hello I have a problem creating simple login with Ldap. I have downloaded getting started project from spring.io website: Getting started LDAP.

It is working perfectly with ldif file but I want to replace it with running ldap server. I have tried it for days with no progress. I get best results with this piece of code (replaced in WebSecurityConfig of getting started project)

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailsService());
    }
 
    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(null, "ldap://ip:port/", "ou=GROUP,dc=domain,dc=com");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
 
        return provider;
    }
}

If i try to login with good username and password in format "username" "password" console output: ActiveDirectoryLdapAuthenticationProvider : Active Directory authentication failed: Supplied password was invalid

If I use "username@domain.com" and good password, page just reloads with no output to console.

If I use random username and password console: Active Directory authentication failed: Supplied password was invalid

Can someone help?


Solution

  • As suggested in comment I have turned on logging and found out that the problem is same with "username@domain.com" too.

    Problem was in aciveDirectoryLdapAuthenticationProvider() there were 3 problems in it.

    1. I have removed OU group from rootDn and added domain so we can use only username to log in.
    ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://ip:port/", "dc=domain,dc=com");
    
    1. changed searchfilter of provider
    provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
    
    1. and finally I had to change ActiveDirectoryLdapAuthProvider searchForUser method because it was matching "username@domain.com" with sAMAccountName istead of "username". This:
    return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,
                        searchControls, searchRoot, searchFilter,
                        new Object[] { bindPrincipal });    
    

    replaced with this:

    return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,
                    searchControls, searchRoot, searchFilter,
                    new Object[] { username }); 
    

    Complete aciveDirectoryLdapAuthenticationProvider:

        @Bean
        public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
            ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://ip:port/", "dc=domain,dc=com");  
            provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
            provider.setConvertSubErrorCodesToExceptions(true);
            provider.setUseAuthenticationRequestCredentials(true);
            return provider;
        }
    

    Can someone provide better solution for the second/third problem? maybe better searchfilter? I dont have any field in ldap that matches "username@domain.com" format of bindPrincipal that is using ActiveDirectoryLdapAuthProvider.