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.

This commit is contained in:
Luke Taylor 2008-12-12 14:27:23 +00:00
parent aec23749d7
commit 48dce501ce
7 changed files with 49 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -19,9 +19,7 @@ package org.springframework.security.context;
* A strategy for storing security context information against a thread. * A strategy for storing security context information against a thread.
* *
* <p> * <p>
* The preferred strategy is loaded by {@link * The preferred strategy is loaded by {@link SecurityContextHolder}.
* org.springframework.security.context.SecurityContextHolder}.
* </p>
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
@ -48,4 +46,12 @@ public interface SecurityContextHolderStrategy {
* <code>null</code> has been passed and throw an <code>IllegalArgumentException</code> in such cases) * <code>null</code> has been passed and throw an <code>IllegalArgumentException</code> in such cases)
*/ */
void setContext(SecurityContext context); 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();
} }

View File

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

View File

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