Remember-me or persistent-login authentication refers to web sites being able to remember the identity of a principal between sessions.
This is typically accomplished by sending a cookie to the browser, with the cookie being detected during future sessions and causing automated login to take place.
Spring Security provides the necessary hooks for these operations to take place, and has two concrete remember-me implementations.
One uses hashing to preserve the security of cookie-based tokens and the other uses a database or other persistent storage mechanism to store the generated tokens.
Note that both implementations require a `UserDetailsService`.
If you are using an authentication provider which doesn't use a `UserDetailsService` (for example, the LDAP provider) then it won't work unless you also have a `UserDetailsService` bean in your application context.
As such the remember-me token is valid only for the period specified, and provided that the username, password and key does not change.
Notably, this has a potential security issue in that a captured remember-me token will be usable from any user agent until such time as the token expires.
This is the same issue as with digest authentication.
If a principal is aware a token has been captured, they can easily change their password and immediately invalidate all remember-me tokens on issue.
If more significant security is needed you should use the approach described in the next section.
If you are familiar with the topics discussed in the chapter on xref:servlet/configuration/xml-namespace.adoc#ns-config[namespace configuration], you can enable remember-me authentication just by adding the `<remember-me>` element:
The `UserDetailsService` will normally be selected automatically.
If you have more than one in your application context, you need to specify which one should be used with the `user-service-ref` attribute, where the value is the name of your `UserDetailsService` bean.
This approach is based on the article https://web.archive.org/web/20180819014446/http://jaspan.com/improved_persistent_login_cookie_best_practice[http://jaspan.com/improved_persistent_login_cookie_best_practice] with some minor modifications footnote:[Essentially, the username is not included in the cookie, to prevent exposing a valid login name unecessarily.
Remember-me is used with `UsernamePasswordAuthenticationFilter`, and is implemented via hooks in the `AbstractAuthenticationProcessingFilter` superclass.
It is also used within `BasicAuthenticationFilter`.
The hooks will invoke a concrete `RememberMeServices` at the appropriate times.
Please refer to the Javadoc for a fuller discussion on what the methods do, although note at this stage that `AbstractAuthenticationProcessingFilter` only calls the `loginFail()` and `loginSuccess()` methods.
The `autoLogin()` method is called by `RememberMeAuthenticationFilter` whenever the `SecurityContextHolder` does not contain an `Authentication`.
This interface therefore provides the underlying remember-me implementation with sufficient notification of authentication-related events, and delegates to the implementation whenever a candidate web request might contain a cookie and wish to be remembered.
This design allows any number of remember-me implementation strategies.
We've seen above that Spring Security provides two implementations.
In addition, `TokenBasedRememberMeServices` requires A UserDetailsService from which it can retrieve the username and password for signature comparison purposes, and generate the `RememberMeAuthenticationToken` to contain the correct ``GrantedAuthority``s.
Some sort of logout command should be provided by the application that invalidates the cookie if the user requests this.
`TokenBasedRememberMeServices` also implements Spring Security's `LogoutHandler` interface so can be used with `LogoutFilter` to have the cookie cleared automatically.
By default, this implementation uses the MD5 algorithm to encode the token signature.
To verify the token signature, the algorithm retrieved from `algorithmName` is parsed and used.
If no `algorithmName` is present, the default matching algorithm will be used, which is MD5.
You can specify different algorithms for signature encoding and for signature matching, this allows users to safely upgrade to a different encoding algorithm while still able to verify old ones if there is no `algorithmName` present.
To do that you can specify your customized `TokenBasedRememberMeServices` as a Bean and use it in the configuration.
Don't forget to add your `RememberMeServices` implementation to your `UsernamePasswordAuthenticationFilter.setRememberMeServices()` property, include the `RememberMeAuthenticationProvider` in your `AuthenticationManager.setProviders()` list, and add `RememberMeAuthenticationFilter` into your `FilterChainProxy` (typically immediately after your `UsernamePasswordAuthenticationFilter`).
You can use this class in the same way as `TokenBasedRememberMeServices`, but it additionally needs to be configured with a `PersistentTokenRepository` to store the tokens.