public class TokenBasedRememberMeServices extends Object implements RememberMeServices, org.springframework.beans.factory.InitializingBean, LogoutHandler
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
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
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 (eg 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) and as such 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.
By default the tokens will be valid for 14 days from the last successful
authentication attempt. This can be changed using
setTokenValiditySeconds(long)
.
Modifier and Type | Field and Description |
---|---|
static String |
ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY |
protected AuthenticationDetailsSource |
authenticationDetailsSource |
static String |
DEFAULT_PARAMETER |
protected static org.apache.commons.logging.Log |
logger |
protected long |
tokenValiditySeconds |
Constructor and Description |
---|
TokenBasedRememberMeServices() |
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet() |
Authentication |
autoLogin(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
This method will be called whenever the
SecurityContextHolder does not contain an
Authentication and the Acegi Security system wishes to provide an implementation with an
opportunity to authenticate the request using remember-me capabilities. |
protected void |
cancelCookie(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
String reasonForLog) |
String |
getCookieName() |
String |
getKey() |
String |
getParameter() |
long |
getTokenValiditySeconds() |
UserDetailsService |
getUserDetailsService() |
boolean |
isAlwaysRemember() |
protected boolean |
isTokenExpired(long tokenExpiryTime) |
protected boolean |
isValidUserDetails(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
UserDetails userDetails,
String[] cookieTokens) |
protected UserDetails |
loadUserDetails(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
String[] cookieTokens) |
void |
loginFail(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Called whenever an interactive authentication attempt was made, but the credentials supplied by the user
were missing or otherwise invalid.
|
void |
loginSuccess(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
Authentication successfulAuthentication)
Called whenever an interactive authentication attempt is successful.
|
void |
logout(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
Authentication authentication)
Causes a logout to be completed.
|
protected javax.servlet.http.Cookie |
makeCancelCookie(javax.servlet.http.HttpServletRequest request) |
protected String |
makeTokenSignature(long tokenExpiryTime,
UserDetails userDetails) |
protected javax.servlet.http.Cookie |
makeValidCookie(String tokenValueBase64,
javax.servlet.http.HttpServletRequest request,
long maxAge) |
protected boolean |
rememberMeRequested(javax.servlet.http.HttpServletRequest request,
String parameter) |
protected String |
retrievePassword(Authentication successfulAuthentication) |
protected String |
retrieveUserName(Authentication successfulAuthentication) |
void |
setAlwaysRemember(boolean alwaysRemember) |
void |
setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) |
void |
setCookieName(String cookieName) |
void |
setKey(String key) |
void |
setParameter(String parameter) |
void |
setTokenValiditySeconds(long tokenValiditySeconds) |
void |
setUserDetailsService(UserDetailsService userDetailsService) |
public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY
public static final String DEFAULT_PARAMETER
protected static final org.apache.commons.logging.Log logger
protected AuthenticationDetailsSource authenticationDetailsSource
protected long tokenValiditySeconds
public void afterPropertiesSet() throws Exception
afterPropertiesSet
in interface org.springframework.beans.factory.InitializingBean
Exception
public Authentication autoLogin(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
RememberMeServices
SecurityContextHolder
does not contain an
Authentication
and the Acegi Security system wishes to provide an implementation with an
opportunity to authenticate the request using remember-me capabilities. Acegi Security makes no attempt
whatsoever to determine whether the browser has requested remember-me services or presented a valid cookie.
Such determinations are left to the implementation. If a browser has presented an unauthorised cookie for
whatever reason, it should be silently ignored and invalidated using the HttpServletResponse
object.The returned Authentication
must be acceptable to AuthenticationManager
or AuthenticationProvider
defined
by the web application. It is recommended RememberMeAuthenticationToken
be used in most cases, as it has a
corresponding authentication provider.
autoLogin
in interface RememberMeServices
request
- to look for a remember-me token withinresponse
- to change, cancel or modify the remember-me tokennull
if the request should not be authenticatedprotected String makeTokenSignature(long tokenExpiryTime, UserDetails userDetails)
tokenExpiryTime
- userDetails
- protected boolean isValidUserDetails(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, UserDetails userDetails, String[] cookieTokens)
protected UserDetails loadUserDetails(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, String[] cookieTokens)
protected boolean isTokenExpired(long tokenExpiryTime)
protected void cancelCookie(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, String reasonForLog)
public String getKey()
public String getParameter()
public long getTokenValiditySeconds()
public UserDetailsService getUserDetailsService()
public void loginFail(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
RememberMeServices
HttpServletRequest
.loginFail
in interface RememberMeServices
request
- that contained an invalid authentication requestresponse
- to change, cancel or modify the remember-me tokenprotected boolean rememberMeRequested(javax.servlet.http.HttpServletRequest request, String parameter)
public void loginSuccess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Authentication successfulAuthentication)
RememberMeServices
HttpServletResponse
, although this is not recommended. Instead,
implementations should typically look for a request parameter that indicates the browser has presented an
explicit request for authentication to be remembered, such as the presence of a HTTP POST parameter.loginSuccess
in interface RememberMeServices
request
- that contained the valid authentication requestresponse
- to change, cancel or modify the remember-me tokensuccessfulAuthentication
- representing the successfully authenticated principalpublic void logout(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Authentication authentication)
LogoutHandler
logout
in interface LogoutHandler
request
- the HTTP requestresponse
- the HTTP resonseauthentication
- the current principal detailsprotected String retrieveUserName(Authentication successfulAuthentication)
protected String retrievePassword(Authentication successfulAuthentication)
protected javax.servlet.http.Cookie makeCancelCookie(javax.servlet.http.HttpServletRequest request)
protected javax.servlet.http.Cookie makeValidCookie(String tokenValueBase64, javax.servlet.http.HttpServletRequest request, long maxAge)
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource)
public void setKey(String key)
public void setParameter(String parameter)
public void setCookieName(String cookieName)
public void setTokenValiditySeconds(long tokenValiditySeconds)
public void setUserDetailsService(UserDetailsService userDetailsService)
public boolean isAlwaysRemember()
public void setAlwaysRemember(boolean alwaysRemember)
public String getCookieName()
Copyright © 2016. All rights reserved.