0

I have set up an ldap authentication using the following configuration. I need user to authenticate using LDAP data store, and in that I have set the pwdMaxFailure to 2.

Authentication is working correctly however every time I login with wrong password I'm getting the following exception instead of Password lock exception. I don't think Spring LDAP is checking the PwdPolicy (Counting the password attempts) while authenticating the user.

ne = (javax.naming.AuthenticationException) javax.naming.AuthenticationException: [LDAP: error code 49 - INVALID_CREDENTIALS: Bind failed: ERR_229 Cannot authenticate user cn=admin,ou=users,o=organisation]

My LDIF file is

dn: cn=admin,ou=users,o=organization objectClass: inetOrgPerson
objectClass: organizationalPerson objectClass: person objectClass: top cn: admin sn: Admin uid: admin userPassword:: e1NTSEF9bEtlTUNzLy9OK1JsV2hCWEM2U2ZZNDh0Lzd0OHBlbjFrdjkxN3c9P Q==
createTimestamp: 20141003000008.689Z creatorsName: 0.9.2342.19200300.100.1.1=admin,2.5.4.11=system entryCSN: 20141020004319.002000Z#000000#001#000000 entryDN: cn=admin,ou=users,o=organization entryParentId: 8204b2df-ff5a-413a-a063-4ac30d35bee4 entryUUID:: N2I1MTFlNjYtMDhjZS00YjA3LWIxYzItNTkyOTI3ZGE3ZTBi modifiersName: 0.9.2342.19200300.100.1.1=admin,2.5.4.11=system modifyTimestamp: 20141020004319.002Z pwdFailureTime: 20141020003207.120Z pwdHistory:: MjAxNDEwMDMwMDAwMDguNjgxWiMxLjMuNi4xLjQuMS4xNDY2LjExNS4xMjEuMS4
0MCM4I1lXUnRhVzQ9 pwdPolicySubentry: cn=default,ou=pwdPolicy,o=organization

dn: cn=default,ou=pwdPolicy,o=organization objectClass: device
objectClass: pwdPolicy objectClass: top cn: default
pwdAttribute: userPassword pwdExpireWarning: 3600 pwdGraceExpire: 1 pwdLockout: TRUE pwdLockoutDuration: 120 pwdMaxAge: 2592000
pwdMaxFailure: 2

And the spring configuration file is as follows

<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
  <authentication-provider ref="jdbcProviderManager" />
  <authentication-provider ref="ldapProviderManager" />      
</authentication-manager>

<bean id="jdbcProviderManager" class="au.com.spring.handler.DBLoginAuthentication">
  <property name="userDetailsService" ref="daoAuthenticationProvider" />
</bean>

<bean id="ldapProviderManager" class="au.com.spring.handler.LDAPLoginAuthentication">
  <property name="userDetailsService" ref="ldapAuthenticationProvider" />
</bean>

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <property name="userDetailsService" ref="JdbcUserDetailsManager" />
  <property name="passwordEncoder" ref="encoder" />
</bean>

<bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
  <constructor-arg>
    <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
      <constructor-arg ref="contextSource" />
      <property name="userSearch" ref="ldapUserSearch" />
    </bean>
  </constructor-arg>
  <constructor-arg>
    <bean class="au.com.spring.handler.CustomLDAPAuthoritiesPopulator">
      <constructor-arg ref="contextSource" />
      <constructor-arg value="${group.search}" />
      <property name="groupSearchFilter" value="${group.search.filter}" />
      <property name="groupRoleAttribute" value="${group.role.att}" />
      <property name="rolePrefix" value="ROLE_" />
      <property name="searchSubtree" value="true" />
      <property name="convertToUpperCase" value="true" />
    </bean>
  </constructor-arg>
  <property name="hideUserNotFoundExceptions" value="false" />
  <property name="useAuthenticationRequestCredentials" value="true" />
  <property name="userDetailsContextMapper" ref="inetOrgPersonContextMapper" />
</bean>

<bean id="inetOrgPersonContextMapper" class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />

<bean id="defaultLdapUsernameToDnMapper" class="org.springframework.security.ldap.DefaultLdapUsernameToDnMapper">
  <constructor-arg value="${users.search}" />
  <constructor-arg value="${uid.att}" />
</bean>
<!--<bean id="authenticationSuccessListener" class="prpa.athos.security.listener.AuthenticationSuccessListener" />-->

<!--<bean id="contextSource" class="org.springframework.security.ldap.ppolicy.PasswordPolicyAwareContextSource">-->
<bean id="contextSource" class="org.springframework.security.ldap.ppolicy.PasswordPolicyAwareContextSource">
  <constructor-arg value="ldap://localhost:10389/o=organization" />
  <!--<property name=""/>-->
</bean>

1 Answer 1

1

I'm getting the following exception instead of Password lock exception.

From the LDAP password policy draft 10:

8.1.1. Fail if the account is locked

If the account is locked as specified in Section 7.1, the server fails the operation with an appropriate resultCode (i.e. invalidCredentials (49) in the case of a bind operation, compareFalse (5) in the case of a compare operation, etc.). The server MAY set the error: accountLocked (1) in the passwordPolicyResponse in the controls field of the message.

So the LDAP server is behaving correctly.

I don't think Spring LDAP is checking the PwdPolicy (Counting the password attempts) while authenticating the user

It is the LDAP server that does the checking. Spring would need to provide the extra request control that enables it to see the password-lock status described above. But in any case you never want to disclose to the user why his login failed at login time: that's an information leak. It amounts to telling the attacker that the username is correct, which is never desirable. Let the user enquire why the login failed if he thinks his password is correct, or let him go through the lost-password sequence.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the quick response. After login failed to create a context (using wrong password), in the catch block of the class PasswordPolicyAwareContextSource it is calling PasswordPolicyControlExtractor.extractControl where the responseControl is null. If not null, it is checking if ctrl is locked. Not sure if I'm doing the right thing, is there any way to get the responseControl not null.
I don't know anything about Spring but in LDAP you have to attach a 'password policy request control' to the request to get a 'password policy response control' with the response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.