Breve descripción

La autenticación Recuérdame o de inicio de sesión persistente se refiere a sitios web que pueden recordar la identidad de un usuario entre sesiones. Por lo general, esto se logra enviando una cookie al navegador, que se detecta durante sesiones posteriores y genera un inicio de sesión automático. Spring Security proporciona los interceptores necesarios para realizar estas operaciones y tiene dos implementaciones específicas de recordarme. Uno utiliza hash para mantener la seguridad de los tokens basados en cookies y el otro utiliza una base de datos u otro mecanismo de almacenamiento persistente para almacenar los tokens generados.

Tenga en cuenta que ambas implementaciones requieren UserDetailsService. Si está utilizando un proveedor de autenticación que no utiliza UserDetailsService (como un proveedor LDAP), no funcionará a menos que también haya un bean UserDetailsService en el contexto de la aplicación. .

Enfoque sencillo utilizando tokens basados en hash

Este enfoque utiliza hash para implementar con éxito la útil estrategia Recuérdame. Básicamente, se envía una cookie al navegador después de una autenticación interactiva exitosa y la cookie consta de los siguientes elementos:


base64(username + ":" + expirationTime + ":" +
md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
username:          que puede determinar el UserDetailsService
password:          Igual que la contenida en los Detalles de usuario recibidos
expirationTime:    Fecha y hora de vencimiento del token recordarme, expresada en milisegundos
key:               clave privada para evitar cambios en el token recordarme
 

Por lo tanto, el token Recuérdame solo es válido durante el período especificado y siempre que el nombre de usuario, la contraseña y la clave no cambien. En particular, existe un posible problema de seguridad en este caso, ya que el token de recuerdo resultante estará disponible para que lo utilice cualquier agente de usuario hasta que caduque. Este es el mismo problema que con la autenticación implícita. Si el director sabe que el token ha sido interceptado, puede cambiar fácilmente su contraseña y revocar inmediatamente todos los tokens de recordarme emitidos. Si se requiere una protección más avanzada, se debe utilizar el enfoque descrito en la siguiente sección. O los servicios Recuérdame no deberían utilizarse en absoluto.

Si está familiarizado con los temas tratados en el capítulo de configuración del espacio de nombres, puede habilitar la autenticación Recordarme simplemente agregando un elemento <remember-me>:

<http>
...
<recordarme key="myAppKey"/>
</http>

El UserDetailsService específico generalmente se selecciona automáticamente. Si tiene más de uno en el contexto de su aplicación, debe especificar cuál usar usando el atributo user-service-ref, donde el valor es el nombre de su bean para UserDetailsService

Enfoque de token persistente

Este enfoque se basa en el artículo http://jaspan.com/improved_persistent_login_cookie_best_practice con algunos cambios menores [1]. Para utilizar este enfoque con la configuración del espacio de nombres, debe proporcionar una referencia a la fuente de datos:

<http>
...
<recuérdame data-source-ref="someDataSource"/>
</http>

La base de datos debe contener una tabla persistent_logins creada utilizando el siguiente SQL (o equivalente):

create table persistent_logins (username varchar(64) not null,
								series varchar(64) primary key,
								token varchar(64) not null,
								last_used timestamp not null)

Interfaces e implementaciones del método Remember-Me

El método Recuérdame se usa con UsernamePasswordAuthenticationFilter y se implementa usando interceptores en la superclase AbstractAuthenticationProcessingFilter. También se utiliza en BasicAuthenticationFilter. Los interceptores llamarán a RememberMeServices específicos en el momento adecuado. La interfaz se ve así:

Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
void loginFail(HttpServletRequest request, HttpServletResponse response);
void loginSuccess(HttpServletRequest request, HttpServletResponse response,
    Authentication successfulAuthentication);

Consulte el Javadoc para obtener una descripción más completa de cómo funcionan estos métodos, aunque en esta etapa tenga en cuenta que AbstractAuthenticationProcessingFilter solo llama a loginFail() y loginSuccess(). El método autoLogin() es llamado por RememberMeAuthenticationFilter siempre que SecurityContextHolder no contiene una Authentication. Por lo tanto, esta interfaz proporciona una implementación básica de recordarme con notificación adecuada de eventos relacionados con la autenticación y le delega autoridad en los casos en que la solicitud web de un candidato pueda contener una cookie y deba recordarse. Esta estructura le permite utilizar cualquier número de estrategias de implementación de recordarme. Aprendimos anteriormente que Spring Security proporciona dos implementaciones. Los veremos uno por uno.

Servicios TokenBasedRememberMe

TokenBasedRememberMeServices genera un RememberMeAuthenticationToken, que es manejado por RememberMeAuthenticationProvider. La instancia key se comparte entre este proveedor de autenticación y TokenBasedRememberMeServices. Además, TokenBasedRememberMeServices requiere una instancia de UserDetailsService de la cual pueda obtener el nombre de usuario y la contraseña para la coincidencia de firmas, así como generar un RememberMeAuthenticationToken para que contenga el correcto GrantedAuthority concedida. La aplicación debe proporcionar algún tipo de comando de cierre de sesión que invalide la cookie si el usuario lo solicita. TokenBasedRememberMeServices también implementa la interfaz LogoutHandler de Spring Security, por lo que se puede utilizar junto con LogoutFilter para borrar automáticamente las cookies.

Los siguientes son los beans que deben estar en el contexto de la aplicación para habilitar los servicios Recuérdame:

<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>

No olvide agregar la implementación RememberMeServices a la propiedad UsernamePasswordAuthenticationFilter.setRememberMeServices(), agregue RememberMeAuthenticationProvider al list AuthenticationManager.setProviders() y agregue RememberMeAuthenticationFilter a FilterChainProxy (generalmente justo después de UsernamePasswordAuthenticationFilter).

Servicios PersistentTokenBasedRememberMe

Esta clase se puede usar de la misma manera que TokenBasedRememberMeServices, pero adicionalmente necesita agregar un PersistentTokenRepository a la configuración para almacenar tokens. Hay dos implementaciones estándar.

  • InMemoryTokenRepositoryImpl, que está destinado únicamente a pruebas.

  • JdbcTokenRepositoryImpl, que almacena tokens en la base de datos>