فهرست منبع

SEC-299: Change ConcurrentSessionFilter to delegate to an array of LogoutHandlers rather than invalidating an expired session directly.

Luke Taylor 17 سال پیش
والد
کامیت
382dc50f3c
1فایلهای تغییر یافته به همراه27 افزوده شده و 7 حذف شده
  1. 27 7
      core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java

+ 27 - 7
core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java

@@ -15,9 +15,13 @@
 
 package org.springframework.security.concurrent;
 
-import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
 import org.springframework.security.ui.FilterChainOrderUtils;
 import org.springframework.security.ui.SpringSecurityFilter;
+import org.springframework.security.ui.logout.LogoutHandler;
+import org.springframework.security.ui.logout.SecurityContextLogoutHandler;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.util.Assert;
 
 import javax.servlet.FilterChain;
@@ -30,13 +34,15 @@ import java.io.IOException;
 
 /**
  * Filter required by concurrent session handling package.
- * <p>This filter performs two functions. First, it calls
- * {@link org.springframework.security.concurrent.SessionRegistry#refreshLastRequest(String)} for each request.
- * That way, registered sessions always have a correct "last update" date/time. Second, it retrieves
+ * <p>
+ * This filter performs two functions. First, it calls
+ * {@link org.springframework.security.concurrent.SessionRegistry#refreshLastRequest(String)} for each request
+ * so that registered sessions always have a correct "last update" date/time. Second, it retrieves a
  * {@link org.springframework.security.concurrent.SessionInformation} from the <code>SessionRegistry</code>
  * for each request and checks if the session has been marked as expired.
- * If it has been marked as expired, the session is invalidated. The invalidation of the session will also cause the
- * request to redirect to the URL specified, and a
+ * If it has been marked as expired, the configured logout handlers will be called (as happens with
+ * {@link org.springframework.security.ui.logout.LogoutFilter}), typically to invalidate the session.
+ * A redirect to the expiredURL specified will be performed, and the session invalidation will cause an
  * {@link org.springframework.security.ui.session.HttpSessionDestroyedEvent} to be published via the
  * {@link org.springframework.security.ui.session.HttpSessionEventPublisher} registered in <code>web.xml</code>.</p>
  *
@@ -48,6 +54,7 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
 
     private SessionRegistry sessionRegistry;
     private String expiredUrl;
+    private LogoutHandler[] handlers = new LogoutHandler[] {new SecurityContextLogoutHandler()};
 
     //~ Methods ========================================================================================================
 
@@ -66,7 +73,7 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
             if (info != null) {
                 if (info.isExpired()) {
                     // Expired - abort processing
-                    session.invalidate();
+                    doLogout(request, response);
 
                     if (expiredUrl != null) {
                         String targetUrl = request.getContextPath() + expiredUrl;
@@ -88,6 +95,14 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
         chain.doFilter(request, response);
     }
 
+    private void doLogout(HttpServletRequest request, HttpServletResponse response) {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        for (int i = 0; i < handlers.length; i++) {
+            handlers[i].logout(request, response, auth);
+        }
+    }
+
     public void setExpiredUrl(String expiredUrl) {
         this.expiredUrl = expiredUrl;
     }
@@ -96,6 +111,11 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
         this.sessionRegistry = sessionRegistry;
     }
 
+    public void setLogoutHandlers(LogoutHandler[] handlers) {
+        Assert.notNull(handlers);        
+        this.handlers = handlers;
+    }
+
     public int getOrder() {
         return FilterChainOrderUtils.CONCURRENT_SESSION_FILTER_ORDER;
     }