'Spring security Ldap authentication Exception : Not an instance of DirContext

I'm trying to connect to a Ldap server (host by the company, don't have much info about it), using Spring Security, I have this bean:

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    DefaultDirObjectFactory factory = new DefaultDirObjectFactory();
    LdapContextSource ldapContextSource = new LdapContextSource();
    ldapContextSource.setAnonymousReadOnly(true);
    ldapContextSource.setUrl("ldap://ldap.company.domain.com:xxxx/dc=company,dc=com");
    ldapContextSource.setDirObjectFactory(factory.getClass());
    auth.ldapAuthentication().userSearchFilter("uid={0}").contextSource(ldapContextSource);
}

But I got this error:

Caused by: org.springframework.ldap.NotContextException: Not an instance of DirContext; nested exception is javax.naming.NotContextException: Not an instance of DirContext at backend-1.0.0-RC1.war//org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:209) at backend-1.0.0-RC1.war//org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:824) at backend-1.0.0-RC1.war//org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:807) at backend-1.0.0-RC1.war//org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:260) at backend-1.0.0-RC1.war//org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:100) at backend-1.0.0-RC1.war//org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:86) at backend-1.0.0-RC1.war//org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:174) ... 101 more Caused by: javax.naming.NotContextException: Not an instance of DirContext at java.naming/javax.naming.directory.InitialDirContext.getURLOrDefaultInitDirCtx(InitialDirContext.java:154) at java.naming/javax.naming.directory.InitialDirContext.search(InitialDirContext.java:326) at java.naming/javax.naming.directory.InitialDirContext.search(InitialDirContext.java:326) at backend-1.0.0-RC1.war//org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java:271) at backend-1.0.0-RC1.war//org.springframework.security.ldap.SpringSecurityLdapTemplate.lambda$searchForSingleEntry$3(SpringSecurityLdapTemplate.java:260) at backend-1.0.0-RC1.war//org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:821) ... 106 more

when doing:

AuthenticationManager.authenticate(authenticateToken)

Because it is working on another projet, using jndi, I know that Ldap info are correct.

Edit: I tried to add:

    Map<String, Object> baseEnvironmentProperties = new HashMap<String, Object>();
    baseEnvironmentProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

But still get the same error.

Do you have any idea why I got this error?



Solution 1:[1]

I have found a working solution using a LdapAuthenticationProvider:

 @Bean
 public AuthenticationProvider ldapAuthenticationProvider() throws Exception {
     DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(List.of("ldap://ldap.company.domain.com:xxx"),"dc=company,dc=com");
     contextSource.setAnonymousReadOnly(true);
     contextSource.afterPropertiesSet();
     LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch("", "uid={0}", contextSource);
     BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
     bindAuthenticator.setUserSearch(ldapUserSearch);
     LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator);
     return ldapAuthenticationProvider;
 }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andronicus