Search code examples
springspring-bootspring-securityactive-directoryldap-query

Is the searchFilter specified with my ADLdapAuthenticationProvider correct for my Active Directory structure?


In my Active directory DC, I have a user named "Demo User" inside the OU "Special Users" of the domain "myCompany.co.hk".

I'm using Spring Security's ActiveDirectoryLdapAuthenticationProvider to authenticate a user against my AD DC over SSL on port 636.

For this AD structure, the filter I'm using in my Authenticator is:

(&(objectCateogry=person)(objectClass=user)(userPrincipalName=Demo User)(memberOf=OU=Special Users,DC=mycompany,DC=co,DC=hk))

When I try to login as this user, providing the username and password in the spring form as is stored in AD, I constantly get "Bad Credentials" although I know that the credentials are indeed correct, which makes me think that perhaps it is an issue with my base filter which is not able to locate the user correctly.

I'm unable to understand what I need to change with my code to authenticate as this user which already exists in the AD DC, any help would be greatly appreciated, Thanks.

Full Code that I'm using is as follows-

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
 protected void configure(HttpSecurity http) throws Exception {
  http
   .authorizeRequests()
   .anyRequest().fullyAuthenticated()
   .and()
   .formLogin();
 }
@Bean
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
  ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = 
  new ActiveDirectoryLdapAuthenticationProvider( "myCompany.co.hk", "ldaps://192.168.1.636");
  activeDirectoryLdapAuthenticationProvider.setConvertSubErrorCodesToExceptions(true); 
  activeDirectoryLdapAuthenticationProvider.
setSearchFilter("(&(objectCateogry=person)(objectClass=user)(userPrincipalName=Demo User)(memberOf=OU=Special Users,DC=myCompany,DC=co,DC=hk))");
  return activeDirectoryLdapAuthenticationProvider;
 }

Solution

  • According to the documentation

    The LDAP filter string to search for the user being authenticated. Occurrences of {0} are replaced with the username@domain. Occurrences of {1} are replaced with the username only.

    Defaults to: (&(objectClass=user)(userPrincipalName={0}))

    So the search filter is not supposed find only one user. It should be written find any user who could possibly be allowed to login to your application. So the filter should not be hardcoded with one specific username. (also, the userPrincipalName cannot contain spaces and always ends with the domain name, so userPrincipalName=Demo User would always be false)

    You should be able to delete the .setSearchFilter() line and let it use the default filter.

    Your other issue is that the memberOf attribute only contains the groups that the user is a member of. It doesn't list the OU that the user is in. If you want only users in the Special Users OU to be able to login, you need to set the rootDn parameter in the constructor:

    ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = 
    new ActiveDirectoryLdapAuthenticationProvider(
        "myCompany.co.hk", "ldaps://192.168.1.636", "OU=Special Users,DC=myCompany,DC=co,DC=hk"
    );