From ef38844a6d9ab9b8c2a29e0a9bb418b0d0105966 Mon Sep 17 00:00:00 2001
From: Vishal Puri
RememberMeServices
+ */
private void autoDetectRememberMeServices() {
if (applicationContext != null) {
Map map = applicationContext.getBeansOfType(RememberMeServices.class);
if (map.size() > 0) {
setRememberMeServices((RememberMeServices) map.values().iterator().next());
- }
+ }
}
}
diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
index c1a684bc15..19ae8590ce 100644
--- a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
+++ b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
@@ -105,12 +105,11 @@ import org.springframework.web.bind.RequestUtils;
* @version $Id: TokenBasedRememberMeServices.java 1871 2007-05-25 03:12:49Z
* benalex $
*/
-public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler, Ordered, ApplicationContextAware {
+public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler, Ordered,
+ ApplicationContextAware {
// ~ Static fields/initializers
// =====================================================================================
-
-
public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY = "ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE";
public static final String DEFAULT_PARAMETER = "_acegi_security_remember_me";
@@ -149,13 +148,14 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
Assert.hasLength(key);
Assert.hasLength(parameter);
Assert.hasLength(cookieName);
- Assert.notNull(applicationContext, "ApplicationContext required");
- if (!isSetUserDetailsServiceInvoked) {
- autoDetectAnyUserDetailsServiceAndUseIt(applicationContext);
+ if (applicationContext != null) {
+ if (!isSetUserDetailsServiceInvoked) {
+ autoDetectAndUseAnyUserDetailsService(applicationContext);
+ }
}
Assert.notNull(userDetailsService);
}
-
+
/**
* Introspects the Applicationcontext for the single instance
* of {@link AccessDeniedHandler}. If found invoke
@@ -166,7 +166,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
*
* @param applicationContext to locate the instance
*/
- private void autoDetectAnyUserDetailsServiceAndUseIt(ApplicationContext applicationContext) {
+ private void autoDetectAndUseAnyUserDetailsService(ApplicationContext applicationContext) {
Map map = applicationContext.getBeansOfType(UserDetailsService.class);
if (map.size() > 1) {
throw new IllegalArgumentException(
@@ -177,7 +177,6 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
setUserDetailsService((UserDetailsService) map.values().iterator().next());
}
}
-
public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
@@ -208,6 +207,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":");
if (cookieTokens.length == 3) {
+
long tokenExpiryTime;
try {
@@ -221,8 +221,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
return null;
}
- // Check it has not expired
- if (tokenExpiryTime < System.currentTimeMillis()) {
+ if (isTokenExpired(tokenExpiryTime)) {
cancelCookie(request, response, "Cookie token[1] has expired (expired on '"
+ new Date(tokenExpiryTime) + "'; current time is '" + new Date() + "')");
@@ -232,25 +231,15 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
// Check the user exists
// Defer lookup until after expiry time checked, to
// possibly avoid expensive lookup
- UserDetails userDetails;
+ UserDetails userDetails = loadUserDetails(request, response, cookieTokens);
- try {
- userDetails = this.userDetailsService.loadUserByUsername(cookieTokens[0]);
- }
- catch (UsernameNotFoundException notFound) {
+ if (userDetails == null) {
cancelCookie(request, response, "Cookie token[0] contained username '" + cookieTokens[0]
+ "' but was not found");
-
return null;
}
- // Immediately reject if the user is not allowed to
- // login
- if (!userDetails.isAccountNonExpired() || !userDetails.isCredentialsNonExpired()
- || !userDetails.isEnabled()) {
- cancelCookie(request, response, "Cookie token[0] contained username '" + cookieTokens[0]
- + "' but account has expired, credentials have expired, or user is disabled");
-
+ if (!isValidUserDetails(request, response, userDetails, cookieTokens)) {
return null;
}
@@ -264,8 +253,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
// (as if the token is valid, it will cause
// SecurityContextHolder population, whilst
// if invalid, will cause the cookie to be cancelled)
- String expectedTokenSignature = DigestUtils.md5Hex(userDetails.getUsername() + ":"
- + tokenExpiryTime + ":" + userDetails.getPassword() + ":" + this.key);
+ String expectedTokenSignature = makeTokenSignature(tokenExpiryTime, userDetails);
if (!expectedTokenSignature.equals(cookieTokens[2])) {
cancelCookie(request, response, "Cookie token[2] contained signature '" + cookieTokens[2]
@@ -304,7 +292,55 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
return null;
}
- private void cancelCookie(HttpServletRequest request, HttpServletResponse response, String reasonForLog) {
+ /**
+ * @param tokenExpiryTime
+ * @param userDetails
+ * @return
+ */
+ protected String makeTokenSignature(long tokenExpiryTime, UserDetails userDetails) {
+ String expectedTokenSignature = DigestUtils.md5Hex(userDetails.getUsername() + ":" + tokenExpiryTime + ":"
+ + userDetails.getPassword() + ":" + this.key);
+ return expectedTokenSignature;
+ }
+
+ protected boolean isValidUserDetails(HttpServletRequest request, HttpServletResponse response,
+ UserDetails userDetails, String[] cookieTokens) {
+ // Immediately reject if the user is not allowed to
+ // login
+ if (!userDetails.isAccountNonExpired() || !userDetails.isCredentialsNonExpired() || !userDetails.isEnabled()) {
+ cancelCookie(request, response, "Cookie token[0] contained username '" + cookieTokens[0]
+ + "' but account has expired, credentials have expired, or user is disabled");
+
+ return false;
+ }
+ return true;
+ }
+
+ protected UserDetails loadUserDetails(HttpServletRequest request, HttpServletResponse response,
+ String[] cookieTokens) {
+ UserDetails userDetails = null;
+
+ try {
+ userDetails = this.userDetailsService.loadUserByUsername(cookieTokens[0]);
+ }
+ catch (UsernameNotFoundException notFound) {
+ cancelCookie(request, response, "Cookie token[0] contained username '" + cookieTokens[0]
+ + "' but was not found");
+
+ return null;
+ }
+ return userDetails;
+ }
+
+ protected boolean isTokenExpired(long tokenExpiryTime) {
+ // Check it has not expired
+ if (tokenExpiryTime < System.currentTimeMillis()) {
+ return true;
+ }
+ return false;
+ }
+
+ protected void cancelCookie(HttpServletRequest request, HttpServletResponse response, String reasonForLog) {
if ((reasonForLog != null) && logger.isDebugEnabled()) {
logger.debug("Cancelling cookie for reason: " + reasonForLog);
}
@@ -356,17 +392,8 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
Assert.notNull(successfulAuthentication.getPrincipal());
Assert.notNull(successfulAuthentication.getCredentials());
- String username;
- String password;
-
- if (successfulAuthentication.getPrincipal() instanceof UserDetails) {
- username = ((UserDetails) successfulAuthentication.getPrincipal()).getUsername();
- password = ((UserDetails) successfulAuthentication.getPrincipal()).getPassword();
- }
- else {
- username = successfulAuthentication.getPrincipal().toString();
- password = successfulAuthentication.getCredentials().toString();
- }
+ String username = retrieveUserName(successfulAuthentication);
+ String password = retrievePassword(successfulAuthentication);
// If unable to find a username and password, just abort as
// TokenBasedRememberMeServices unable to construct a valid token in
@@ -375,9 +402,6 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
return;
}
- Assert.hasLength(username);
- Assert.hasLength(password);
-
long expiryTime = System.currentTimeMillis() + (tokenValiditySeconds * 1000);
// construct token to put in cookie; format is:
@@ -400,6 +424,28 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
+ (authentication == null ? "Unknown" : authentication.getName()));
}
+ protected String retrieveUserName(Authentication successfulAuthentication) {
+ if (isInstanceOfUserDetails(successfulAuthentication)) {
+ return ((UserDetails) successfulAuthentication.getPrincipal()).getUsername();
+ }
+ else {
+ return successfulAuthentication.getPrincipal().toString();
+ }
+ }
+
+ protected String retrievePassword(Authentication successfulAuthentication) {
+ if (isInstanceOfUserDetails(successfulAuthentication)) {
+ return ((UserDetails) successfulAuthentication.getPrincipal()).getPassword();
+ }
+ else {
+ return successfulAuthentication.getCredentials().toString();
+ }
+ }
+
+ private boolean isInstanceOfUserDetails(Authentication authentication) {
+ return authentication.getPrincipal() instanceof UserDetails;
+ }
+
protected Cookie makeCancelCookie(HttpServletRequest request) {
Cookie cookie = new Cookie(cookieName, null);
cookie.setMaxAge(0);
@@ -459,7 +505,11 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext=applicationContext;
+ this.applicationContext = applicationContext;
+ }
+
+ public String getCookieName() {
+ return cookieName;
}
}