3

Appologies for the long question, but I in short I'm wondering how do I set the org.springframework.ldap.core.LdapTemplate#ignorePartialResultException flag using Spring Java Config.

The long winded question is...

I want to use our companies Active Directory for authentication (by this I mean user/password checking) to start off with, and then after that works for authorisation (so which roles they have permission to use).

I took the spring ldap guide and made changes to connect to our companies Active Directory instead of using the guide's LDIF file. I know from debugging that the program connects to the Active directory and authenticates the user correctly but when retrieving the authorities I get the following exception:

Unprocessed Continuation Reference(s); nested exception is javax.naming.PartialResultException

From googling I saw this was a common LDAP/ActiveDirectory problem and I need to set the flags to ignore referrals. I followed the example from this SO question. However I still get the exception and from debugging I can see the error is occurring in the following method when searching for roles for the user.

org.springframework.ldap.core.LdapTemplate#search(org.springframework.ldap.core.SearchExecutor, org.springframework.ldap.core.NameClassPairCallbackHandler, org.springframework.ldap.core.DirContextProcessor) 

For reference my WebSecurityConfig file:

    @Bean
    public BaseLdapPathContextSource contextSource() throws Exception {
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://<ad-host>:389/");

        contextSource.setUserDn(/*principleCN*/);
        contextSource.setPassword(/*principlePassword*/);
        contextSource.setReferral("ignore"); 
        contextSource.afterPropertiesSet();

        return contextSource;
    }

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.ldapAuthentication()
                .userSearchFilter("(&(sAMAccountName={0})(objectclass=user))")
                .userSearchBase("dc=<company>,dc=local")
                .groupSearchBase("dc=<company>,dc=local")
                .contextSource(contextSource());
    }
Community
  • 1
  • 1
user1232555
  • 1,099
  • 3
  • 11
  • 18

1 Answers1

6

For what I can tell you can achieve this via the DefaultLdapAuthoritiesPopulator, it has a setIgnorePartialResultException(boolean) method to achieve exactly this.

So in your config class you would need to do something along the following lines:

@Bean
public LdapAuthoritiesPopulator ldapAuthoritiesPopulator() throws Exception {
    DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(contextSource(), "dc=<company>,dc=local");
    populator.setIgnorePartialResultException(true);
    return populator;
}

@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
    auth.ldapAuthentication()
            .userSearchFilter("(&(sAMAccountName={0})(objectclass=user))")
            .userSearchBase("dc=<company>,dc=local")
            .contextSource(contextSource())
            .ldapAuthoritiesPopulator(ldapAuthoritiesPopulator());
}

One caveat is that I have not explicitly tested this so you may need to play around with your config a bit.

DB5
  • 13,553
  • 7
  • 66
  • 71
  • in ldapAuthoritiesPopulator where is contextSource() coming from? – JavaSheriff Apr 16 '19 at 13:45
  • 1
    @user648026, it is a method which returns a `BaseLdapPathContextSource`. It is defined in @user1232555's question in the WebSecurityConfig class. My answer was given to fit their question. – DB5 Apr 16 '19 at 20:22