1
0
mirror of synced 2026-08-03 16:56:56 +00:00

SEC-1229: Redesign Concurrent Session Control implementation. Added ConcurrentSessionControlAuthenticatedSessionStrategy

This commit is contained in:
Luke Taylor
2009-08-27 10:43:01 +00:00
parent ab0d66071a
commit 471206a29d
13 changed files with 377 additions and 198 deletions
@@ -54,37 +54,6 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
Assert.notNull(this.messages, "A message source must be set");
}
/**
* 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 allowableSessions the number of concurrent sessions the user is allowed to have
* @param registry an instance of the <code>SessionRegistry</code> for subclass use
*
* @throws ConcurrentLoginException if the
*/
protected void allowableSessionsExceeded(String sessionId, List<SessionInformation> sessions, int allowableSessions,
SessionRegistry registry) {
if (exceptionIfMaximumExceeded || (sessions == null)) {
throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed",
new Object[] {new Integer(allowableSessions)},
"Maximum sessions of {0} for this principal exceeded"));
}
// Determine least recently used session, and mark it for invalidation
SessionInformation leastRecentlyUsed = null;
for (int i = 0; i < sessions.size(); i++) {
if ((leastRecentlyUsed == null)
|| sessions.get(i).getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
leastRecentlyUsed = sessions.get(i);
}
}
leastRecentlyUsed.expireNow();
}
public void checkAuthenticationAllowed(Authentication request) throws AuthenticationException {
Assert.notNull(request, "Authentication request cannot be null (violation of interface contract)");
@@ -120,6 +89,43 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry);
}
/**
* 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 allowableSessions the number of concurrent sessions the user is allowed to have
* @param registry an instance of the <code>SessionRegistry</code> for subclass use
*
* @throws ConcurrentLoginException if the
*/
protected void allowableSessionsExceeded(String sessionId, List<SessionInformation> sessions, int allowableSessions,
SessionRegistry registry) {
if (exceptionIfMaximumExceeded || (sessions == null)) {
throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed",
new Object[] {new Integer(allowableSessions)},
"Maximum sessions of {0} for this principal exceeded"));
}
// Determine least recently used session, and mark it for invalidation
SessionInformation leastRecentlyUsed = null;
for (int i = 0; i < sessions.size(); i++) {
if ((leastRecentlyUsed == null)
|| sessions.get(i).getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
leastRecentlyUsed = sessions.get(i);
}
}
leastRecentlyUsed.expireNow();
}
public void registerSuccessfulAuthentication(Authentication authentication) {
Assert.notNull(authentication, "Authentication cannot be null (violation of interface contract)");
sessionRegistry.registerNewSession(obtainSessionId(authentication), authentication.getPrincipal());
}
/**
* 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
@@ -133,12 +139,6 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
return maximumSessions;
}
public void registerSuccessfulAuthentication(Authentication authentication) {
Assert.notNull(authentication, "Authentication cannot be null (violation of interface contract)");
sessionRegistry.registerNewSession(obtainSessionId(authentication), authentication.getPrincipal());
}
public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) {
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
}
@@ -41,7 +41,7 @@ public interface SessionRegistry {
* @param includeExpiredSessions if <code>true</code>, the returned sessions will also include those that have
* expired for the principal
*
* @return the matching sessions for this principal, or <code>null</code> if none were found
* @return the matching sessions for this principal (should not return null).
*/
List<SessionInformation> getAllSessions(Object principal, boolean includeExpiredSessions);