|
@@ -1,4 +1,4 @@
|
|
|
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
|
|
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -18,30 +18,35 @@ package org.acegisecurity.concurrent;
|
|
|
import org.acegisecurity.AcegiMessageSource;
|
|
|
import org.acegisecurity.Authentication;
|
|
|
import org.acegisecurity.AuthenticationException;
|
|
|
+
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
+
|
|
|
import org.springframework.context.MessageSource;
|
|
|
import org.springframework.context.MessageSourceAware;
|
|
|
import org.springframework.context.support.MessageSourceAccessor;
|
|
|
+
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Base implementation of {@link ConcurrentSessionControllerImpl} which
|
|
|
* prohibits simultaneous logins.
|
|
|
+ *
|
|
|
* <p>
|
|
|
- * By default uses {@link SessionRegistryImpl},
|
|
|
- * although any <code>SessionRegistry</code> may be used.
|
|
|
+ * By default uses {@link SessionRegistryImpl}, although any
|
|
|
+ * <code>SessionRegistry</code> may be used.
|
|
|
* </p>
|
|
|
*
|
|
|
* @author Ben Alex
|
|
|
* @version $Id$
|
|
|
*/
|
|
|
-public class ConcurrentSessionControllerImpl implements ConcurrentSessionController,
|
|
|
- InitializingBean, MessageSourceAware {
|
|
|
-
|
|
|
+public class ConcurrentSessionControllerImpl
|
|
|
+ implements ConcurrentSessionController, InitializingBean,
|
|
|
+ MessageSourceAware {
|
|
|
//~ Instance fields ========================================================
|
|
|
|
|
|
- protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
|
|
|
+ protected MessageSourceAccessor messages = AcegiMessageSource
|
|
|
+ .getAccessor();
|
|
|
private SessionRegistry sessionRegistry = new SessionRegistryImpl();
|
|
|
private boolean exceptionIfMaximumExceeded = false;
|
|
|
private int maximumSessions = 1;
|
|
@@ -51,7 +56,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
public void afterPropertiesSet() throws Exception {
|
|
|
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
|
|
Assert.isTrue(maximumSessions != 0,
|
|
|
- "MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
|
|
+ "MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
|
|
Assert.notNull(this.messages, "A message source must be set");
|
|
|
}
|
|
|
|
|
@@ -59,21 +64,22 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
* Allows subclasses to customise behaviour when too many sessions are
|
|
|
* detected.
|
|
|
*
|
|
|
- * @param sessionId the session ID of the present request
|
|
|
- * @param sessions either <code>null</code> or all unexpired sessions
|
|
|
- * associated with the principal
|
|
|
+ * @param sessionId the session ID of the present request
|
|
|
+ * @param sessions either <code>null</code> or all unexpired sessions
|
|
|
+ * associated with the principal
|
|
|
* @param allowableSessions DOCUMENT ME!
|
|
|
- * @param registry an instance of the <code>SessionRegistry</code> for
|
|
|
- * subclass use
|
|
|
+ * @param registry an instance of the <code>SessionRegistry</code> for
|
|
|
+ * subclass use
|
|
|
+ *
|
|
|
* @throws ConcurrentLoginException DOCUMENT ME!
|
|
|
*/
|
|
|
protected void allowableSessionsExceeded(String sessionId,
|
|
|
- SessionInformation[] sessions, int allowableSessions,
|
|
|
- SessionRegistry registry) {
|
|
|
+ SessionInformation[] sessions, int allowableSessions,
|
|
|
+ SessionRegistry registry) {
|
|
|
if (exceptionIfMaximumExceeded || (sessions == null)) {
|
|
|
throw new ConcurrentLoginException(messages.getMessage(
|
|
|
"ConcurrentSessionControllerImpl.exceededAllowed",
|
|
|
- new Object[]{new Integer(allowableSessions)},
|
|
|
+ new Object[] {new Integer(allowableSessions)},
|
|
|
"Maximum sessions of {0} for this principal exceeded"));
|
|
|
}
|
|
|
|
|
@@ -82,8 +88,8 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
|
|
|
for (int i = 0; i < sessions.length; i++) {
|
|
|
if ((leastRecentlyUsed == null)
|
|
|
- || sessions[i].getLastRequest()
|
|
|
- .before(leastRecentlyUsed.getLastRequest())) {
|
|
|
+ || sessions[i].getLastRequest()
|
|
|
+ .before(leastRecentlyUsed.getLastRequest())) {
|
|
|
leastRecentlyUsed = sessions[i];
|
|
|
}
|
|
|
}
|
|
@@ -92,16 +98,17 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
}
|
|
|
|
|
|
public void checkAuthenticationAllowed(Authentication request)
|
|
|
- throws AuthenticationException {
|
|
|
+ throws AuthenticationException {
|
|
|
Assert.notNull(request,
|
|
|
- "Authentication request cannot be null (violation of interface contract)");
|
|
|
+ "Authentication request cannot be null (violation of interface contract)");
|
|
|
|
|
|
Object principal = SessionRegistryUtils
|
|
|
- .obtainPrincipalFromAuthentication(request);
|
|
|
+ .obtainPrincipalFromAuthentication(request);
|
|
|
String sessionId = SessionRegistryUtils
|
|
|
- .obtainSessionIdFromAuthentication(request);
|
|
|
+ .obtainSessionIdFromAuthentication(request);
|
|
|
|
|
|
- SessionInformation[] sessions = sessionRegistry.getAllSessions(principal);
|
|
|
+ SessionInformation[] sessions = sessionRegistry.getAllSessions(principal,
|
|
|
+ false);
|
|
|
|
|
|
int sessionCount = 0;
|
|
|
|
|
@@ -111,7 +118,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
|
|
|
int allowableSessions = getMaximumSessionsForThisUser(request);
|
|
|
Assert.isTrue(allowableSessions != 0,
|
|
|
- "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
|
|
+ "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
|
|
|
|
|
if (sessionCount < allowableSessions) {
|
|
|
return;
|
|
@@ -124,41 +131,40 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- allowableSessionsExceeded(sessionId, sessions,
|
|
|
- allowableSessions, sessionRegistry);
|
|
|
+ allowableSessionsExceeded(sessionId, sessions, allowableSessions,
|
|
|
+ sessionRegistry);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Method intended for use by subclasses to override the maximum
|
|
|
- * number of sessions that are permitted for a particular
|
|
|
- * authentication. The default implementation simply returns the
|
|
|
- * <code>maximumSessions</code> value for the bean.
|
|
|
+ * Method intended for use by subclasses to override the maximum number of
|
|
|
+ * sessions that are permitted for a particular authentication. The
|
|
|
+ * default implementation simply returns the <code>maximumSessions</code>
|
|
|
+ * value for the bean.
|
|
|
*
|
|
|
* @param authentication to determine the maximum sessions for
|
|
|
- * @return either -1 meaning unlimited, or a positive integer to
|
|
|
- * limit (never zero)
|
|
|
+ *
|
|
|
+ * @return either -1 meaning unlimited, or a positive integer to limit
|
|
|
+ * (never zero)
|
|
|
*/
|
|
|
- protected int getMaximumSessionsForThisUser(
|
|
|
- Authentication authentication) {
|
|
|
+ protected int getMaximumSessionsForThisUser(Authentication authentication) {
|
|
|
return maximumSessions;
|
|
|
}
|
|
|
|
|
|
- public void registerSuccessfulAuthentication(
|
|
|
- Authentication authentication) {
|
|
|
+ public void registerSuccessfulAuthentication(Authentication authentication) {
|
|
|
Assert.notNull(authentication,
|
|
|
- "Authentication cannot be null (violation of interface contract)");
|
|
|
+ "Authentication cannot be null (violation of interface contract)");
|
|
|
|
|
|
Object principal = SessionRegistryUtils
|
|
|
- .obtainPrincipalFromAuthentication(authentication);
|
|
|
+ .obtainPrincipalFromAuthentication(authentication);
|
|
|
String sessionId = SessionRegistryUtils
|
|
|
- .obtainSessionIdFromAuthentication(authentication);
|
|
|
+ .obtainSessionIdFromAuthentication(authentication);
|
|
|
|
|
|
sessionRegistry.removeSessionInformation(sessionId);
|
|
|
sessionRegistry.registerNewSession(sessionId, principal);
|
|
|
}
|
|
|
|
|
|
public void setExceptionIfMaximumExceeded(
|
|
|
- boolean exceptionIfMaximumExceeded) {
|
|
|
+ boolean exceptionIfMaximumExceeded) {
|
|
|
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
|
|
|
}
|
|
|
|
|
@@ -170,8 +176,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
|
|
|
this.messages = new MessageSourceAccessor(messageSource);
|
|
|
}
|
|
|
|
|
|
- public void setSessionRegistry(
|
|
|
- SessionRegistry sessionRegistry) {
|
|
|
+ public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
|
|
this.sessionRegistry = sessionRegistry;
|
|
|
}
|
|
|
}
|