2
votes

Using JNDI I can successfully authenticate against our LDAP server, which has anonymous binds disabled, using only the user's username and password, like this:

    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, url);

    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, userName);
    env.put(Context.SECURITY_CREDENTIALS, password);
    DirContext ctx = new InitialDirContext(env);
    Attribute groups = ctx.getAttributes(userName).get("groupMembership");

Now I would like to do the same thing using Spring Boot, Spring Security, and Spring LDAP.

I can successfully configure authentication using a bind DN and password, like this:

    DefaultSpringSecurityContextSource context = new DefaultSpringSecurityContextSource(ldapConfig.url);
    context.setUserDn(ldapConfig.bindDn);
    String bindPassword = passwordResolver.getPassword(ldapConfig.password);
    context.setPassword(bindPassword);
    context.afterPropertiesSet();

    CustomAuthoritiesPopulator customAuthoritiesPopulator = new CustomAuthoritiesPopulator(context, ldapConfig.groupSearchBase);

    String[] dnPatArr = new String[ldapConfig.userDnPatterns.size()];
    ldapConfig.userDnPatterns.toArray(dnPatArr);

    auth.ldapAuthentication()
        .ldapAuthoritiesPopulator(customAuthoritiesPopulator)
        .contextSource(context)
        .userDnPatterns(dnPatArr)
        .groupSearchBase(ldapConfig.groupSearchBase);

This works--the Spring Boot webapp will authenticate my users successfully.

But I would like to do this without passing in the bind DN and bind password, just like I did with the JNDI example.

If I simply omit setting the bind DN and password, I will get "LDAP: error code 48 - Anonymous Simple Bind Disabled.".

I don't want to do an anonymous bind--I want Spring to use the username and password the user provides to do a simple bind against each of my bind DN patterns until one works.

I've read the docs but I'm having a hard time determining whether or not that is possible. JNDI can do it so I figure I should be able to get Spring to do it. I've thought about writing my own custom Spring Security authentication provider but surely that's not necessary.

1

1 Answers

0
votes

In the JNDI, authentication information is specified in environment properties. Please make sure the property names are spelled correctly.

For example environment property for credentials is java.naming.security.credentials not java.naming.security.credential. Notice the missing letter 's' at the end would give

"LDAP: error code 48 - Anonymous Simple Bind Disabled."

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">      
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</prop>
            <prop key="java.naming.provider.url">ldap://serverURL/jndi_ctx
            </prop>
            <prop key="java.naming.security.authentication">simple</prop>
            <prop key="java.naming.security.principal">user_id</prop>
            <prop key="java.naming.security.credentials">password</prop>            
        </props>
    </property>
</bean>