org.acegisecurity.ui.rememberme
Class TokenBasedRememberMeServices

java.lang.Object
  extended by org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices
All Implemented Interfaces:
LogoutHandler, RememberMeServices, org.springframework.beans.factory.InitializingBean

public class TokenBasedRememberMeServices
extends Object
implements RememberMeServices, org.springframework.beans.factory.InitializingBean, LogoutHandler

Identifies previously remembered users by a Base-64 encoded cookie.

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).

Version:
$Id: TokenBasedRememberMeServices.java 1871 2007-05-25 03:12:49Z benalex $
Author:
Ben Alex

Field Summary
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 Summary
TokenBasedRememberMeServices()
           
 
Method Summary
 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)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY

public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY
See Also:
Constant Field Values

DEFAULT_PARAMETER

public static final String DEFAULT_PARAMETER
See Also:
Constant Field Values

logger

protected static final org.apache.commons.logging.Log logger

authenticationDetailsSource

protected AuthenticationDetailsSource authenticationDetailsSource

tokenValiditySeconds

protected long tokenValiditySeconds
Constructor Detail

TokenBasedRememberMeServices

public TokenBasedRememberMeServices()
Method Detail

afterPropertiesSet

public void afterPropertiesSet()
                        throws Exception
Specified by:
afterPropertiesSet in interface org.springframework.beans.factory.InitializingBean
Throws:
Exception

autoLogin

public Authentication autoLogin(javax.servlet.http.HttpServletRequest request,
                                javax.servlet.http.HttpServletResponse response)
Description copied from interface: RememberMeServices
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. 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.

Specified by:
autoLogin in interface RememberMeServices
Parameters:
request - to look for a remember-me token within
response - to change, cancel or modify the remember-me token
Returns:
a valid authentication object, or null if the request should not be authenticated

makeTokenSignature

protected String makeTokenSignature(long tokenExpiryTime,
                                    UserDetails userDetails)
Parameters:
tokenExpiryTime -
userDetails -
Returns:

isValidUserDetails

protected boolean isValidUserDetails(javax.servlet.http.HttpServletRequest request,
                                     javax.servlet.http.HttpServletResponse response,
                                     UserDetails userDetails,
                                     String[] cookieTokens)

loadUserDetails

protected UserDetails loadUserDetails(javax.servlet.http.HttpServletRequest request,
                                      javax.servlet.http.HttpServletResponse response,
                                      String[] cookieTokens)

isTokenExpired

protected boolean isTokenExpired(long tokenExpiryTime)

cancelCookie

protected void cancelCookie(javax.servlet.http.HttpServletRequest request,
                            javax.servlet.http.HttpServletResponse response,
                            String reasonForLog)

getKey

public String getKey()

getParameter

public String getParameter()

getTokenValiditySeconds

public long getTokenValiditySeconds()

getUserDetailsService

public UserDetailsService getUserDetailsService()

loginFail

public void loginFail(javax.servlet.http.HttpServletRequest request,
                      javax.servlet.http.HttpServletResponse response)
Description copied from interface: RememberMeServices
Called whenever an interactive authentication attempt was made, but the credentials supplied by the user were missing or otherwise invalid. Implementations should invalidate any and all remember-me tokens indicated in the HttpServletRequest.

Specified by:
loginFail in interface RememberMeServices
Parameters:
request - that contained an invalid authentication request
response - to change, cancel or modify the remember-me token

rememberMeRequested

protected boolean rememberMeRequested(javax.servlet.http.HttpServletRequest request,
                                      String parameter)

loginSuccess

public void loginSuccess(javax.servlet.http.HttpServletRequest request,
                         javax.servlet.http.HttpServletResponse response,
                         Authentication successfulAuthentication)
Description copied from interface: RememberMeServices
Called whenever an interactive authentication attempt is successful. An implementation may automatically set a remember-me token in the 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.

Specified by:
loginSuccess in interface RememberMeServices
Parameters:
request - that contained the valid authentication request
response - to change, cancel or modify the remember-me token
successfulAuthentication - representing the successfully authenticated principal

logout

public void logout(javax.servlet.http.HttpServletRequest request,
                   javax.servlet.http.HttpServletResponse response,
                   Authentication authentication)
Description copied from interface: LogoutHandler
Causes a logout to be completed. The method must complete successfully.

Specified by:
logout in interface LogoutHandler
Parameters:
request - the HTTP request
response - the HTTP resonse
authentication - the current principal details

retrieveUserName

protected String retrieveUserName(Authentication successfulAuthentication)

retrievePassword

protected String retrievePassword(Authentication successfulAuthentication)

makeCancelCookie

protected javax.servlet.http.Cookie makeCancelCookie(javax.servlet.http.HttpServletRequest request)

makeValidCookie

protected javax.servlet.http.Cookie makeValidCookie(String tokenValueBase64,
                                                    javax.servlet.http.HttpServletRequest request,
                                                    long maxAge)

setAuthenticationDetailsSource

public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource)

setKey

public void setKey(String key)

setParameter

public void setParameter(String parameter)

setCookieName

public void setCookieName(String cookieName)

setTokenValiditySeconds

public void setTokenValiditySeconds(long tokenValiditySeconds)

setUserDetailsService

public void setUserDetailsService(UserDetailsService userDetailsService)

isAlwaysRemember

public boolean isAlwaysRemember()

setAlwaysRemember

public void setAlwaysRemember(boolean alwaysRemember)

getCookieName

public String getCookieName()


Copyright © 2004-2009 Interface21, Inc. All Rights Reserved.