Преглед на файлове

SEC-942: Added createEmptyContext() method to SecurityContextHolderStrategy and SecurityContextHolder to encapsulate the context implemetentation in one place. HttpSessionSecurityContextRepository calls this method when it needs a new context to store in the session.

Luke Taylor преди 17 години
родител
ревизия
48dce501ce

+ 8 - 3
core/src/main/java/org/springframework/security/context/GlobalSecurityContextHolderStrategy.java

@@ -19,9 +19,10 @@ import org.springframework.util.Assert;
 
 
 /**
- * A <code>static</code> field-based implementation of {@link
- * org.springframework.security.context.SecurityContextHolderStrategy}.<p>This means that all instances in the JVM share the
- * same <code>SecurityContext</code>. This is generally useful with rich clients, such as Swing.</p>
+ * A <code>static</code> field-based implementation of {@link SecurityContextHolderStrategy}.
+ * <p>
+ * This means that all instances in the JVM share the
+ * same <code>SecurityContext</code>. This is generally useful with rich clients, such as Swing.
  *
  * @author Ben Alex
  * @version $Id$
@@ -49,4 +50,8 @@ public class GlobalSecurityContextHolderStrategy implements SecurityContextHolde
         Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
         contextHolder = context;
     }
+
+    public SecurityContext createEmptyContext() {
+        return new SecurityContextImpl();
+    }
 }

+ 13 - 6
core/src/main/java/org/springframework/security/context/HttpSessionSecurityContextRepository.java

@@ -180,19 +180,26 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
     }
 
     /**
-     * By default, returns an instance of {@link SecurityContextImpl}.
-     * If a custom <tt>SecurityContext</tt> implementation is in use (i.e. the <tt>securityContextClass</tt> property
-     * is set), it will attempt to invoke the no-args constructor on the supplied class instead and return the created
-     * instance.
+     * By default, calls {@link SecurityContextHolder#createEmptyContext()} to obtain a new context (there should be
+     * no context present in the holder when this method is called). Using this approach the context creation
+     * strategy is decided by the {@link SecurityContextHolderStrategy} in use. The default implementations
+     * will return a new <tt>SecurityContextImpl</tt>.
+     * <p>
+     * An alternative way of customizing the <tt>SecurityContext</tt> implementation is by setting the
+     * <tt>securityContextClass</tt> property. In this case, the method will attempt to invoke the no-args
+     * constructor on the supplied class instead and return the created instance.
      *
      * @return a new SecurityContext instance. Never null.
      */
     SecurityContext generateNewContext() {
+        SecurityContext context = null;
+
         if (securityContextClass == null) {
-            return new SecurityContextImpl();
+            context = SecurityContextHolder.createEmptyContext();
+
+            return context;
         }
 
-        SecurityContext context = null;
         try {
             context = securityContextClass.newInstance();
         } catch (Exception e) {

+ 5 - 1
core/src/main/java/org/springframework/security/context/InheritableThreadLocalSecurityContextHolderStrategy.java

@@ -26,7 +26,7 @@ import org.springframework.util.Assert;
  * @version $Id$
  *
  * @see java.lang.ThreadLocal
- * @see org.springframework.security.context.HttpSessionContextIntegrationFilter
+ * @see org.springframework.security.context.SecurityContextPersistenceFilter
  */
 public class InheritableThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
     //~ Static fields/initializers =====================================================================================
@@ -51,4 +51,8 @@ public class InheritableThreadLocalSecurityContextHolderStrategy implements Secu
         Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
         contextHolder.set(context);
     }
+
+    public SecurityContext createEmptyContext() {
+        return new SecurityContextImpl();
+    }
 }

+ 7 - 0
core/src/main/java/org/springframework/security/context/SecurityContextHolder.java

@@ -135,6 +135,13 @@ public class SecurityContextHolder {
         initialize();
     }
 
+    /**
+     * Delegates the creation of a new, empty context to the configured strategy.
+     */
+    static SecurityContext createEmptyContext() {
+        return strategy.createEmptyContext();
+    }
+
     public String toString() {
         return "SecurityContextHolder[strategy='" + strategyName + "'; initializeCount=" + initializeCount + "]";
     }

+ 9 - 3
core/src/main/java/org/springframework/security/context/SecurityContextHolderStrategy.java

@@ -19,9 +19,7 @@ package org.springframework.security.context;
  * A strategy for storing security context information against a thread.
  *
  * <p>
- * The preferred strategy is loaded by {@link
- * org.springframework.security.context.SecurityContextHolder}.
- * </p>
+ * The preferred strategy is loaded by {@link SecurityContextHolder}.
  *
  * @author Ben Alex
  * @version $Id$
@@ -48,4 +46,12 @@ public interface SecurityContextHolderStrategy {
      *        <code>null</code> has been passed and throw an <code>IllegalArgumentException</code> in such cases)
      */
     void setContext(SecurityContext context);
+
+    /**
+     * Creates a new, empty context implementation, for use by <tt>SecurityContextRepository</tt> implementations,
+     * when creating a new context for the first time.
+     *
+     * @return the empty context.
+     */
+    SecurityContext createEmptyContext();
 }

+ 1 - 1
core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java

@@ -61,9 +61,9 @@ public class SecurityContextPersistenceFilter extends SpringSecurityFilter {
         }
 
         HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
+        SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
 
         try {
-            SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
             SecurityContextHolder.setContext(contextBeforeChainExecution);
 
             chain.doFilter(holder.getRequest(), holder.getResponse());

+ 6 - 3
core/src/main/java/org/springframework/security/context/ThreadLocalSecurityContextHolderStrategy.java

@@ -19,14 +19,13 @@ import org.springframework.util.Assert;
 
 
 /**
- * A <code>ThreadLocal</code>-based implementation of {@link
- * org.springframework.security.context.SecurityContextHolderStrategy}.
+ * A <code>ThreadLocal</code>-based implementation of {@link SecurityContextHolderStrategy}.
  *
  * @author Ben Alex
  * @version $Id$
  *
  * @see java.lang.ThreadLocal
- * @see org.springframework.security.context.HttpSessionContextIntegrationFilter
+ * @see org.springframework.security.context.SecurityContextPersistenceFilter
  */
 public class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
     //~ Static fields/initializers =====================================================================================
@@ -51,4 +50,8 @@ public class ThreadLocalSecurityContextHolderStrategy implements SecurityContext
         Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
         contextHolder.set(context);
     }
+
+    public SecurityContext createEmptyContext() {
+        return new SecurityContextImpl();
+    }
 }