title: Spring-Security-Ldap - How to report Locked Account
body: <p>I have a properly working Spring-LDAP instance configured against ApacheDS.</p>
  
  <p>Pretty vanilla security context:</p>
  
  <pre><code>&lt;authentication-manager alias="authenticationManager"&gt;
      &lt;ldap-authentication-provider
          user-context-mapper-ref="detailsMapper"
          user-dn-pattern="uid={0},ou=people" user-search-filter="(uid={0})"
          group-search-base="ou=groups" group-search-filter="member={0}"&gt;
      &lt;/ldap-authentication-provider&gt;
  &lt;/authentication-manager&gt;
  </code></pre>
  
  <p>When an account gets locked, I see in the debug where the lock is acknowledged:</p>
  
  <pre><code>DEBUG: org.springframework.security.ldap.authentication.BindAuthenticator - Failed to bind as uid=lorin,ou=people: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - INVALID_CREDENTIALS: Bind failed: account will remain locked till Sun Jun 07 22:17:01 EDT 2015]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - INVALID_CREDENTIALS: Bind failed: account will remain locked till Sun Jun 07 22:17:01 EDT 2015]
  DEBUG: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Login credentials not found
  DEBUG: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
  DEBUG: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@521758c5
  DEBUG: org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler - No failure URL set, sending 401 Unauthorized error
  DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
  DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
  </code></pre>
  
  <p>But by the time the exception makes it back to my failure handler the exception is strictly a BadCredentialsException with nothing more than my configured messages statement.</p>
  
  <pre><code>public abstract class AbstractLockDetectingAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
  private final static Logger logger = LoggerFactory .getLogger(AbstractLockDetectingAuthenticationFailureHandler.class);
  
  final protected static Locale locale = Locale.getDefault();
  
  @Resource(name="messageSource")
  private ReloadableResourceBundleMessageSource messages;
  
  @Override
  public void onAuthenticationFailure(final HttpServletRequest request,
          final HttpServletResponse response, final AuthenticationException exception)
                  throws IOException, ServletException {
  
      exception.printStackTrace();
  
      super.onAuthenticationFailure(request, response, exception);
  }
  </code></pre>
  
  <p><em>How can I report a locked account vs. a bad password without having to customize a class and subsequently throw myself in to configuration hell for a single message?</em></p>
  
  <p>(And yes, I know its bad form to report locked v. bad password as it leaks security ... insistent customer)</p>