diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java index 02877de2cb..7b99a6a35a 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java @@ -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. + * *

- * By default uses {@link SessionRegistryImpl}, - * although any SessionRegistry may be used. + * By default uses {@link SessionRegistryImpl}, although any + * SessionRegistry may be used. *

* * @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 null or all unexpired sessions - * associated with the principal + * @param sessionId the session ID of the present request + * @param sessions either null or all unexpired sessions + * associated with the principal * @param allowableSessions DOCUMENT ME! - * @param registry an instance of the SessionRegistry for - * subclass use + * @param registry an instance of the SessionRegistry 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 - * maximumSessions 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 maximumSessions + * 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; } } diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java index b022ca8c19..2eccd0d8f9 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistry.java @@ -34,15 +34,20 @@ public interface SessionRegistry { /** * Obtains all the known sessions for the specified principal. Sessions - * that have expired or destroyed are not returned. + * that have been destroyed are not returned. Sessions that have expired + * may be returned, depending on the passed argument. * * @param principal to locate sessions for (should never be * null) + * @param includeExpiredSessions if true, the returned + * sessions will also include those that have expired for the + * principal * - * @return the unexpired and undestroyed sessions for this principal, or - * null if none were found + * @return the matching sessions for this principal, or null + * if none were found */ - public SessionInformation[] getAllSessions(Object principal); + public SessionInformation[] getAllSessions(Object principal, + boolean includeExpiredSessions); /** * Obtains the session information for the specified diff --git a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryImpl.java b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryImpl.java index f5aae8b5db..0e83b299da 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryImpl.java +++ b/core/src/main/java/org/acegisecurity/concurrent/SessionRegistryImpl.java @@ -64,7 +64,8 @@ public class SessionRegistryImpl implements SessionRegistry, return principals.keySet().toArray(); } - public SessionInformation[] getAllSessions(Object principal) { + public SessionInformation[] getAllSessions(Object principal, + boolean includeExpiredSessions) { Set sessionsUsedByPrincipal = (Set) principals.get(principal); if (sessionsUsedByPrincipal == null) { @@ -79,7 +80,7 @@ public class SessionRegistryImpl implements SessionRegistry, String sessionId = (String) iter.next(); SessionInformation sessionInformation = getSessionInformation(sessionId); - if (!sessionInformation.isExpired()) { + if (includeExpiredSessions || !sessionInformation.isExpired()) { list.add(sessionInformation); } }