public class TokenBasedRememberMeServices extends AbstractRememberMeServices
This implementation does not rely on an external database, so is attractive for simple
applications. The cookie will be valid for a specific period from the date of the last
AbstractRememberMeServices.loginSuccess(HttpServletRequest, HttpServletResponse, Authentication)
. As per
the interface contract, this method will only be called when the principal completes a
successful interactive authentication. As such the time period commences from the last
authentication attempt where they furnished credentials - not the time period they last
logged in via remember-me. The implementation will only send a remember-me token if the
parameter defined by AbstractRememberMeServices.setParameter(String)
is present.
An UserDetailsService
is required
by this implementation, so that it can construct a valid Authentication
from the returned UserDetails
.
This is also necessary so that the user's password is available and can be checked as
part of the encoded cookie.
The cookie encoded by this implementation adopts the following form:
username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)
As such, if the user changes their password, any remember-me token will be invalidated. Equally, the system administrator may invalidate every remember-me token on issue by changing the key. This provides some reasonable approaches to recovering from a remember-me token being left on a public machine (e.g. kiosk system, Internet cafe etc). Most importantly, at no time is the user's password ever sent to the user agent, providing an important security safeguard. Unfortunately the username is necessary in this implementation (as we do not want to rely on a database for remember-me services). High security applications should be aware of this occasionally undesired disclosure of a valid username.
This is a basic remember-me implementation which is suitable for many applications.
However, we recommend a database-based implementation if you require a more secure
remember-me approach (see PersistentTokenBasedRememberMeServices
).
By default the tokens will be valid for 14 days from the last successful authentication
attempt. This can be changed using AbstractRememberMeServices.setTokenValiditySeconds(int)
. If this value
is less than zero, the expiryTime will remain at 14 days, but the negative
value will be used for the maxAge property of the cookie, meaning that it will
not be stored when the browser is closed.
DEFAULT_PARAMETER, logger, messages, SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, TWO_WEEKS_S
Constructor and Description |
---|
TokenBasedRememberMeServices(java.lang.String key,
UserDetailsService userDetailsService) |
Modifier and Type | Method and Description |
---|---|
protected int |
calculateLoginLifetime(javax.servlet.http.HttpServletRequest request,
Authentication authentication)
Calculates the validity period in seconds for a newly generated remember-me login.
|
protected boolean |
isTokenExpired(long tokenExpiryTime) |
protected java.lang.String |
makeTokenSignature(long tokenExpiryTime,
java.lang.String username,
java.lang.String password)
Calculates the digital signature to be put in the cookie.
|
void |
onLoginSuccess(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
Authentication successfulAuthentication)
Called from loginSuccess when a remember-me login has been requested.
|
protected UserDetails |
processAutoLoginCookie(java.lang.String[] cookieTokens,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Called from autoLogin to process the submitted persistent login cookie.
|
protected java.lang.String |
retrievePassword(Authentication authentication) |
protected java.lang.String |
retrieveUserName(Authentication authentication) |
afterPropertiesSet, autoLogin, cancelCookie, createSuccessfulAuthentication, decodeCookie, encodeCookie, extractRememberMeCookie, getAuthenticationDetailsSource, getCookieName, getKey, getParameter, getTokenValiditySeconds, getUserDetailsService, loginFail, loginSuccess, logout, onLoginFail, rememberMeRequested, setAlwaysRemember, setAuthenticationDetailsSource, setAuthoritiesMapper, setCookie, setCookieDomain, setCookieName, setParameter, setTokenValiditySeconds, setUserDetailsChecker, setUseSecureCookie
public TokenBasedRememberMeServices(java.lang.String key, UserDetailsService userDetailsService)
protected UserDetails processAutoLoginCookie(java.lang.String[] cookieTokens, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
AbstractRememberMeServices
processAutoLoginCookie
in class AbstractRememberMeServices
cookieTokens
- the decoded and tokenized cookie valuerequest
- the requestresponse
- the response, to allow the cookie to be modified if required.protected java.lang.String makeTokenSignature(long tokenExpiryTime, java.lang.String username, java.lang.String password)
protected boolean isTokenExpired(long tokenExpiryTime)
public void onLoginSuccess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Authentication successfulAuthentication)
AbstractRememberMeServices
onLoginSuccess
in class AbstractRememberMeServices
protected int calculateLoginLifetime(javax.servlet.http.HttpServletRequest request, Authentication authentication)
The returned value will be used to work out the expiry time of the token and will also be used to set the maxAge property of the cookie. See SEC-485.
request
- the request passed to onLoginSuccessauthentication
- the successful authentication object.protected java.lang.String retrieveUserName(Authentication authentication)
protected java.lang.String retrievePassword(Authentication authentication)