package org.beanfuse.security.concurrent; import java.util.List; import org.beanfuse.security.Authentication; import org.beanfuse.security.AuthenticationException; import org.beanfuse.security.online.OnlineActivity; public class ConcurrentSessionControllerImpl implements ConcurrentSessionController { protected SessionRegistry sessionRegistry; private boolean exceptionIfMaximumExceeded = false; private int maximumSessions = 1; /** * allowableSessionsExceeded * * @param sessionId * @param sessions * @param allowableSessions * @param registry * @see checkAuthenticationAllowed */ protected boolean allowableSessionsExceeded(String sessionId, List sessions, int allowableSessions, SessionRegistry registry) { if (exceptionIfMaximumExceeded || (sessions == null)) { return false; } // Determine least recently used session, and mark it for invalidation OnlineActivity leastRecentlyUsed = null; for (int i = 0; i < sessions.size(); i++) { if ((leastRecentlyUsed == null) || ((OnlineActivity) sessions.get(i)).getLastAccessAt().before( leastRecentlyUsed.getLastAccessAt())) { leastRecentlyUsed = (OnlineActivity) sessions.get(i); } } leastRecentlyUsed.expireNow(); return true; } public boolean checkAuthenticationAllowed(Authentication request) throws AuthenticationException { Object principal = request.getPrincipal(); String sessionId = ((SessionIdentifierAware) request.getDetails()).getSessionId(); List sessions = sessionRegistry.getOnlineActivities(principal, false); int sessionCount = 0; if (sessions != null) { sessionCount = sessions.size(); } int allowableSessions = getMaximumSessionsForThisUser(request); if (sessionCount < allowableSessions) { return true; } else if (allowableSessions == -1) { return true; } else if (sessionCount == allowableSessions) { for (int i = 0; i < sessionCount; i++) { if (((OnlineActivity) sessions.get(i)).getSessionid().equals(sessionId)) { return true; } } } return 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. * * @param authentication * to determine the maximum sessions for * * @return either -1 meaning unlimited, or a positive integer to limit * (never zero) */ protected int getMaximumSessionsForThisUser(Authentication authentication) { return maximumSessions; } public void registerAuthentication(Authentication authentication) { String sessionId = ((SessionIdentifierAware) authentication.getDetails()).getSessionId(); sessionRegistry.register(sessionId, authentication); } public void removeAuthentication(String sessionId) { sessionRegistry.remove(sessionId); } public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) { this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded; } public void setMaximumSessions(int maximumSessions) { this.maximumSessions = maximumSessions; } public OnlineActivity getOnlineActivity(String sessionId) { return sessionRegistry.getOnlineActivity(sessionId); } public List getOnlineActivities() { return sessionRegistry.getOnlineActivities(); } public boolean isRegisted(Object principal) { return sessionRegistry.isRegisted(principal); } public void setSessionRegistry(SessionRegistry sessionRegistry) { this.sessionRegistry = sessionRegistry; } }