2
votes

I know almost nothing about LDAP and even less about spring security but I am trying to configure a spring boot app to authenticate against an ldap instance and am stuck.

I was given the ldap server name at adldap.company.com and base dn of dc=ad,dc=company,dc=com

I have some python code that does a simple bind and works.

LDAP_USERNAME = '[email protected]'
LDAP_PASSWORD = 'password'
base_dn = 'dc=ad,dc=company,dc=com' # not used for bind I guess, only search
try:
    ldap_client = ldap.initialize('ldap://adldap.company.com')
    ldap_client.set_option(ldap.OPT_REFERRALS,0)
    ldap_client.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD)
except ldap.INVALID_CREDENTIALS as e:
    ldap_client.unbind()
    return 'Wrong username and password: %s' % e
except ldap.SERVER_DOWN:
   return 'AD server not available'

If I run this code, it seems to successfully bind as "[email protected]" with password "password".

I also have a WebSecurityConfig class that I think should be handling auth:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/secure")
            .authorizeRequests()
            .anyRequest().fullyAuthenticated()
            .and()
            .httpBasic();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
            .userDnPatterns("uid={0}")
            .contextSource()
            .url("ldap://adldap.company.com");
            //.url("ldap://adldap.company.com/dc=ad,dc=company,dc=com");
    }
}

When I go to /secure in the app, I get a basic auth pop up but then anything I try entering gets me a 401 Unauthorized. I have tried "[email protected]", without the domain, putting that stuff in the userDnPatterns like {0}@adldap.company.com and a bunch of other things. I have tried using different URLs with the base dn in it or not. Nothing seems to work. What am I missing?

Also, is this the right way to auth users? I've read about both bind authentication and something about binding and searching but the server doesn't allow anonyous binds so I guess I would need some kind of "app user" that could bind and do the searches, right? Is that "better"?

2
Did you enabled DEBUG logging on org.springframework.security.ldap ?Sébastien Helbert
Yea, it gives me basically an InvalidCredentials error. But the password is fine, I just think there's something about the formatting that's wrong.MichaelB
@SébastienHelbert I know it has been a while, but I am facing similar problems atm. Could u have a look at my question and see, if you might have had the same troubles and can help me solving them? :)Rüdiger

2 Answers

6
votes

Active Directory has its own non-standard syntax for user authentication, different from the usual LDAP DN binding.

Spring Security provides a specialized AuthenticationProvider for Active Directory.

Try this :

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/secure")
            .authorizeRequests()
            .anyRequest().fullyAuthenticated()
            .and()
            .httpBasic();
    }

    @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 provider = new ActiveDirectoryLdapAuthenticationProvider("adldap.company.com", "ldap://adldap.company.com");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }
}
0
votes

Long story short, the problem is that Microsoft Active Directory LDAP is not "Vanilla" LDAP and thus you need to connect to it differently.

The working solution is here: https://medium.com/@dmarko484/spring-boot-active-directory-authentication-5ea04969f220