Spring ldap authentication failed error codes

2019-08-02 18:01发布

问题:

I'm using Spring LDAP (1.3.1) to talk to ADAM and Active Directory.

When I try to authenticate someone using ldapTemplate.authenticate() I get back errors via the error callback, but it gives a very generic exception AuthenticationException and I cannot extract what exactly is the problem:

  • account disabled
  • password expired
  • must change password on next login
  • account expired
  • etc

All I get back is a detailMessage which I assume is what AD sends back. Something like:

org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 8009030C: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 773, v1db0

I can see data 773, which means the user must change the password at next login. I don't want to parse this manually. Are there any "adapters" I am not aware of?

Did anyone ever had this problem?

Thanks a lot!

回答1:

This link lists how ldap error codes map to JNDI Exceptions. Looking at spring ldap code, it appears that spring maps each JNDI exception to its custom LDAP exception (LdapUtils.convertLdapException())

Now, 773 seems specfic to Active Directory. Hence this needs to be handled by user explicitly, if required. This link lists a bunch of Active Directory errors. Spring ldap would provide this text in its error details, leaving the user to use them as suitable.



回答2:

if your code ends up in PasswordPolicyAwareContextSource.getContext or in similar spring code, Spring does not handle it very well (bug).
When the account is expired an exception is thrown. the above class catches this exception and then, and this is the key, it calls
PasswordPolicyResponseControl ctrl = PasswordPolicyControlExtractor.extractControl(ctx);
Spring then calls ctrl.isLocked() but fails to check for any of the other conditions. You should override Spring's code, and you can check ctrl.isExpired(), ctrl.isChangeAfterReset(), and a bunch of other information getters are available there at that point