@Override public void onAuthentication( Authentication authentication, HttpServletRequest request, HttpServletResponse response) throws SessionAuthenticationException { ClusterSecurityContext context = (ClusterSecurityContext) securityContextRepository.loadContext(new HttpRequestResponseHolder(request, response)); context.setAuthentication(authentication); // filter total max sessions first if (maxSessions > 0) { int postAuthSessionCount = 1; // the login Collection<String> sessionIds = securityContextRepository.getClusterSessionIdsForPrinciple(authentication); postAuthSessionCount += sessionIds.size(); if (postAuthSessionCount > maxSessions) { purgeSessions(request, sessionIds, postAuthSessionCount - maxSessions); } } // filter client type sessions if (maxSessionsByClientType != null) { Collection<ClientType> clientTypes = clientTypeResolver.resolveClientType(request); if (clientTypes != null) { int maxClientTypeSessions = 0; int postAuthSessionCount = 0; Collection<String> sessionIds = null; for (ClientType type : clientTypes) { if (maxSessionsByClientType.containsKey(type)) { postAuthSessionCount = 1; // the login maxClientTypeSessions = maxSessionsByClientType.get(type); sessionIds = securityContextRepository.getClusterSessionIdsForPrinciple(authentication, type); postAuthSessionCount += sessionIds.size(); if (postAuthSessionCount > maxClientTypeSessions) { purgeSessions(request, sessionIds, postAuthSessionCount - maxClientTypeSessions); } } } } } // session fixation if ((context.getClusterSessionId() == null) || sessionFixation) { if (context.getClusterSessionId() != null) { securityContextRepository.expire(request, context.getClusterSessionId()); } context.setClusterSessionId(clusterSessionIdGenerator.generate(request)); clusterSessionIdResolver.sendClusterSessionId( request, response, context.getClusterSessionId()); } context.setAuthTimestamp(System.currentTimeMillis()); context.setLastUpdateTimestamp(System.currentTimeMillis()); securityContextRepository.saveContext(context, request, response); }
private void purgeSessions( HttpServletRequest request, Collection<String> sessionIds, int sessionCount) { Collection<ClusterSecurityContext> contexts = new ArrayList<ClusterSecurityContext>(); boolean lastUpdatesComplete = true; ClusterSecurityContext context = null; for (String id : sessionIds) { context = securityContextRepository.loadById(id); if (context != null) { if (context.getLastUpdateTimestamp() == 0) { lastUpdatesComplete = false; } contexts.add(context); } } Map<Long, String> sortedSessions = new TreeMap<Long, String>(); for (ClusterSecurityContext ctx : contexts) { if (lastUpdatesComplete) { sortedSessions.put(ctx.getLastUpdateTimestamp(), ctx.getClusterSessionId()); } else { sortedSessions.put(ctx.getAuthTimestamp(), ctx.getClusterSessionId()); } } Iterator<String> itr = sortedSessions.values().iterator(); int purgedCount = 0; while (itr.hasNext() && (purgedCount < sessionCount)) { if (maxSessionsByClientType != null) { securityContextRepository.expire(request, itr.next(), maxSessionsByClientType.keySet()); } else { securityContextRepository.expire(request, itr.next()); } purgedCount++; } }