Lockout de cuentas de usuario con Spring Security

...

En la siguiente entrada se resumen los aspectos a tener en cuenta para implementar la funcionalidad de Lockout en las cuentas de usuario de una aplicación Java utilizando Spring Security

¿A que denominamos Account Lockout?

Lockout es el nombre del mecanismo mediante el cual se bloquea la cuenta de un usuario luego de intentar varias veces sin éxito el inicio de sesión en un sistema determinado.

El bloqueo de las cuentas se realiza para evitar los ataques de agentes mal intencionados que pretenden inferir la contraseña de un usuario por diversos mecanismos, como fuerza bruta, ingeniería social, etc.

Acerca de ala implementación utilizando Spring

Spring Security permite extender el comportamiento de uno de sus filtros (AuthenticationProcessingFilter) de forma que se pueda hacer uso de los métodos onSuccesfullAuthentication() y onUnSuccesfullAuthentication().

Para bloquear la cuenta de un usuario, tras una cantidad determinada de intentos erroneos de login, se deben seguir los siguientes pasos:

  • Crear una clase CustomAuthProcFilter que extienda de AuthenticationProcessingFilter.
  • Agregar en la clase correspondiente a los usuarios la propiedad failedLoginAttempts, en la misma se almacenará el número de intentos de login erroneos. Este contador se irá incrementando por cada login erróneo y se volverá a cero por cada inicio de sesión exitoso.
  • Dado que la clase correspondiente a los usuarios debe extender la clase UserDetails, la misma deberá contener el método isAccountNonLocked(), en caso de haber llegado a la máxima cantidad permitida de intentos de login, este método tendrá que retornar false.

Cuando el método isAccountNonLocked() retorna false, Spring Security se encarga de lanzar una excepcion por usuario bloqueado.

Cambios en la configuración del applicationContext

El CustomAuthProcFilter, como se ha dicho anteriormente reemplazará al AuthenticationProcessingFilter, por lo que deberá declararse con ese id en el applicationContext:

<beans:bean id="authenticationProcessingFilter" 
  class="com.springsecuritypoc.web.CustomAuthProcFilter">         
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />         
<beans:property name="defaultTargetUrl" value="/main.jsp" />         
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureUrl" value="/index.jsp? authfailed=true" />
<beans:property name="userManager" ref="userManager" />  
</beans:bean>

Se debe tener en cuenta que la configuración del filtro reemplaza el elemento <form-login&gt declarado dentro de <http&gt, por ello será necesario remover la siguiente declaración:

<form-login  login-page="/jsp/login.jsp" 
  authentication-failure-url="/jsp/login.jsp?login_error=1" 
  default-target-url="/jsp/index.jsp"/>

Métodos de la clase CustomAuthProcessingFilter

A continuación se muestran la implementación de los métodos onSuccessfulAuthentication y onUnsuccessfulAuthenticationde la clase correspondiente al filtro modificado:

@Override    
protected void onSuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, 
Authentication authResult) throws IOException {         
super.onSuccessfulAuthentication(request, response, authResult);         
request.getUserPrincipal();
String authName = authResult.getName();
User userError = userManager.getUserByUsername(authName);		
....	
}

@Override
protected void onUnsuccessfulAuthentication(HttpServletRequest request, 
HttpServletResponse response, 
AuthenticationException failed) {
try {
super.onUnsuccessfulAuthentication(request, response, failed);	 
String authName = failed.getAuthentication().getName();		
User userError = userManager.getUserByUsername(authName);		
....			
}

Diagramas de secuencia

A continuación se incluyen dos diagramas que capturan las secuencias de logien exitoso y login fallido.

Secuencia de un inicio de sesión exitoso

Incio de sesión exitoso

Secuencia de un inicio de sesión fallido

Inicio de sesión fallido

Referencias


Modificado por última vez en Domingo, 17 Noviembre 2013 05:33

Acerca del autor

Gaston Iriarte

Gaston es Ingeniero en Sistemas y cuenta con mas de 6 años de experiencia en el diseño y construcción de aplicaciones Web bajo plataformas Java EE.