views:

318

answers:

1

I can bind to an embedded ldap server on my local machine with the following bean:

<b:bean id="secondLdapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <b:constructor-arg>
        <b:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <b:constructor-arg ref="contextSource" />
            <b:property name="userSearch">
                <b:bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
                  <b:constructor-arg index="0" value="ou=people"/>
                  <b:constructor-arg index="1" value="(uid={0})"/>
                  <b:constructor-arg index="2" ref="contextSource" />
                </b:bean>
            </b:property>
        </b:bean>
    </b:constructor-arg>
    <b:constructor-arg>
        <b:bean class="com.company.security.ldap.BookinLdapAuthoritiesPopulator">
        </b:bean>
    </b:constructor-arg>
</b:bean>

however, when I try to authenticate with a PasswordComparisonAuthenticator it repeatedly fails on a bad credentials event:

 <b:bean id="ldapAuthProvider"
    class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <b:constructor-arg>
        <b:bean
            class="org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator">
            <b:constructor-arg ref="contextSource" />
            <b:property name="userDnPatterns">
                <b:list>
                    <b:value>uid={0},ou=people</b:value>
                </b:list>
            </b:property>
        </b:bean>
    </b:constructor-arg>
    <b:constructor-arg>
        <b:bean class="com.company.security.ldap.BookinLdapAuthoritiesPopulator">
        </b:bean>
    </b:constructor-arg>
</b:bean>

Through debugging, I can see that the authenticate method picks up the DN from the ldif file, but then tries to compare the passwords, however, it's using the LdapShaPasswordEncoder (the default one) where the password is stored in plaintext in the file, and this is where the authentication fails.

Here's the authentication manager bean referencing the preferred authentication bean:

<authentication-manager>

    <authentication-provider ref="ldapAuthProvider"/>

    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="md5" base64="true">
            <salt-source system-wide="secret"/>
        </password-encoder>
    </authentication-provider>
</authentication-manager>

On a side note, whether I set the password-encoder on ldapAuthProvider to plaintext or just leave it blank, doesn't seem to make a difference. Any help would be greatly appreciated.

Thanks

A: 

I was able to override the default LdapShaPasswordEncoder in the PasswordComparisonAuthenticator by injecting a PlainTextPasswordEncoder into the passwordEncoder property:

 <b:bean id="ldapAuthProvider"
    class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <b:constructor-arg>
        <b:bean
            class="org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator">
            <b:constructor-arg ref="contextSource" />
            <b:property name="passwordEncoder">
                <b:bean class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"></b:bean>
            </b:property>
            <b:property name="userDnPatterns">
                <b:list>
                    <b:value>uid={0},ou=people</b:value>
                </b:list>
            </b:property>
        </b:bean>
    </b:constructor-arg><b:constructor-arg>
        <b:bean class="com.company.security.ldap.BookinLdapAuthoritiesPopulator">
        </b:bean>
    </b:constructor-arg>
</b:bean>

And now it doesn't convert the provided input to SHA before comparing...

denlab