Frage

I am trying to configure spring security with LDAP. It works fine with the default user-service but I am unable to authenticate user when I configure LDAP in security context. Following is my security configiration:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security 
                    http://www.springframework.org/schema/security/spring-security-3.1.xsd">


       <beans:bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <beans:constructor-arg value="ldap://authserver:389/dc=mydomain,dc=net"/>
    </beans:bean>
      <beans:bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <beans:constructor-arg ref="ldapContextSource"/>
                <beans:property name="userDnPatterns">
                    <beans:list>
                        <beans:value>uid={0},ou=people</beans:value>
                    </beans:list>
                </beans:property>
            </beans:bean>
        </beans:constructor-arg>
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
                <beans:constructor-arg ref="ldapContextSource"/>
                <beans:constructor-arg value="ou=Groups"/>
                <beans:property name="groupRoleAttribute" value="cn"/>
            </beans:bean>
        </beans:constructor-arg>
    </beans:bean>

 <authentication-manager>
   <authentication-provider ref="ldapAuthProvider" />
</authentication-manager>
<http use-expressions="true">
    <intercept-url pattern="/index" access="permitAll" />
    <intercept-url pattern="/login" access="permitAll"/>
    <intercept-url pattern="/loginfailed" access="permitAll" />
    <intercept-url pattern ="/failure" access="permitAll"/>
    <intercept-url pattern="/home" access="permitAll"/>
    <intercept-url pattern="/resources/**" access="permitAll" />
    <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
    <intercept-url pattern="/secure/**" access="isAuthenticated()" />
    <!--  intercept-url pattern="/**" access="denyAll" / -->
    <form-login login-page="/login" default-target-url="/secure" 
             authentication-failure-url="/loginfailed" />
           <logout logout-success-url="/index" />  

</http>
</beans:beans>

When I provide the username and password using the login form, I see following lines in the log:

07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 1 of 9 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
07:37:47 [http-bio-8181-exec-57] HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
07:37:47 [http-bio-8181-exec-57] HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@d3b8dae. A new one will be created.
07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 2 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
07:37:47 [http-bio-8181-exec-57] FilterChainProxy - /j_spring_security_check at position 3 of 9 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
07:37:47 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Request is to process authentication
07:37:47 [http-bio-8181-exec-57] ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
07:37:47 [http-bio-8181-exec-57] LdapAuthenticationProvider - Processing authentication request for user: testuser
07:37:47 [http-bio-8181-exec-57] BindAuthenticator - Attempting to bind as uid=testuser,ou=people,dc=mydomain
07:37:47 [http-bio-8181-exec-57] DefaultSpringSecurityContextSource - Removing pooling flag for user uid=testuser,ou=people,dc=mydomain
07:37:48 [http-bio-8181-exec-57] BindAuthenticator - Failed to bind as uid=testuser,ou=people: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
07:37:48 [http-bio-8181-exec-57] UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@23ec84dc
07:37:48 [http-bio-8181-exec-57] SimpleUrlAuthenticationFailureHandler - Redirecting to /loginfailed
07:37:48 [http-bio-8181-exec-57] DefaultRedirectStrategy - Redirecting to '/skweb/loginfailed'

I have tried various combinations after using earch on this and othe sites but obviously I am missing something very basic.

**** Update I tried using a simple java program using UnboundID sdk to try and authenticate to the same ldap server and it connected on first attempt.

This simply indicates that there is something incorrect in my Spring configuration but I am unable to find it. I have tried with BindAuthenticator as well as Password comparison method. Is there some configuration in spring security which might cause password to be encrypted in a different scheme than our ldap server?

    static boolean authenticate(String username, String password) throws LDAPException {
    LDAPConnection ldap = new LDAPConnection("authserver", 389);
    SearchResult sr = ldap.search("ou=people,dc=mydomain,dc=net", SearchScope.SUB, "(uid=" + username + ")");
    if (sr.getEntryCount() == 0)
        return false;

    String dn = sr.getSearchEntries().get(0).getDN();

    try {
        ldap = new LDAPConnection("authserver", 389, dn, password);
        return true;
    }
    catch (LDAPException e) {
        if (e.getResultCode() == ResultCode.INVALID_CREDENTIALS)
            return false;

        throw e;
    }
}
War es hilfreich?

Lösung

Solution by OP.

I was able to resolve this after changing the security context as follows:

  <authentication-manager>   
    <ldap-authentication-provider user-search-filter="(uid={0})"
      user-search-base="ou=people"
      group-role-attribute="cn" 
      group-search-base="ou=group"
      group-search-filter="(memberUid={1})"/> 
 </authentication-manager> 

The user-search-filter was the missing piece. The previous entry (uid={0},ou=people) caused incorrect look up in ldap because it used uid instead of cn in format. The search filter explicitly uses the uid for searching the id in ou=people.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top