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>