소스 검색

SEC-1561: HttpSessionSecurityContextRepository should check whether the session contains the context attribute in case a new session has been created during the request. If the attribute is empty, then the context should be stored regardless of whether a change is detected or not.

Luke Taylor 15 년 전
부모
커밋
1724d1eac6
1개의 변경된 파일12개의 추가작업 그리고 10개의 파일을 삭제
  1. 12 10
      web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java

+ 12 - 10
web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java

@@ -1,11 +1,5 @@
 package org.springframework.security.web.context;
 
-import java.lang.reflect.Method;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.security.authentication.AuthenticationTrustResolver;
@@ -14,9 +8,12 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextHolderStrategy;
-import org.springframework.util.Assert;
 import org.springframework.util.ReflectionUtils;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
 /**
  * A {@code SecurityContextRepository} implementation which stores the security context in the {@code HttpSession}
  * between requests.
@@ -69,7 +66,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
      * Gets the security context for the current request (if available) and returns it.
      * <p>
      * If the session is null, the context object is null or the context object stored in the session
-     * is not an instance of <tt>SecurityContext</tt>, a new context object will be generated and
+     * is not an instance of {@code SecurityContext}, a new context object will be generated and
      * returned.
      */
     public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
@@ -280,9 +277,10 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
             }
 
             // If HttpSession exists, store current SecurityContextHolder contents but only if
-            // the SecurityContext has actually changed in this thread (see JIRA SEC-37, SEC-1307, SEC-1528)
+            // the SecurityContext has actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)
             if (httpSession != null) {
-                if (context != contextBeforeExecution || context.getAuthentication() != authBeforeExecution) {
+                // We may have a new session, so check also whether the context attribute is set SEC-1561
+                if (contextChanged(context) || httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null) {
                     httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, context);
 
                     if (logger.isDebugEnabled()) {
@@ -292,6 +290,10 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
             }
         }
 
+        private boolean contextChanged(SecurityContext context) {
+            return context != contextBeforeExecution || context.getAuthentication() != authBeforeExecution;
+        }
+
         private HttpSession createNewSessionIfAllowed(SecurityContext context) {
             if (httpSessionExistedAtStartOfRequest) {
                 if (logger.isDebugEnabled()) {