title: How to keep SecurityContext set through WithSecurityContextFactory in Spring Security tests?
body: <p>I'm using Spring 4.1.5 and Spring Security 4.0.0.RELEASE.</p>
  
  <p>I read <a href="http://spring.io/blog/2014/05/07/preview-spring-security-test-method-security" rel="nofollow">http://spring.io/blog/2014/05/07/preview-spring-security-test-method-security</a> (nice article by Rob Winch) and developed my own implementation of WithSecurityContextFactory to be able to test my Spring MVC controllers:</p>
  
  <pre><code>public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory&lt;WithMockCustomUser&gt; {
  
      @Override
      public SecurityContext createSecurityContext(WithMockCustomUser customUser) {
          final User fakeUser = new User();
          final SecurityUser principal = new SecurityUser(fakeUser);
          final Authentication auth = new UsernamePasswordAuthenticationToken(principal, "password", HelpersTest.getAuthorities(customUser.faps()));
  
          final SecurityContext context = SecurityContextHolder.createEmptyContext();
          context.setAuthentication(auth);
  
          return context;
      }
  }
  </code></pre>
  
  <p>My abstract resource test class is as follow:</p>
  
  <pre><code>    @RunWith(SpringJUnit4ClassRunner.class)
      @WebAppConfiguration
      @ContextConfiguration(locations =
      {
      "classpath:spring/mock-daos-and-scan-for-services.xml",
      "classpath:security.xml",
      "classpath:singletons.xml",
      "classpath:controller-scan.xml",
      "classpath:servlet.xml" })
      @TestExecutionListeners(listeners=
      {
      ServletTestExecutionListener.class,
      DependencyInjectionTestExecutionListener.class,
      DirtiesContextTestExecutionListener.class,
      TransactionalTestExecutionListener.class,
      WithSecurityContextTestExcecutionListener.class })
  
      public abstract class AbstractResourceMockMvcTest {
  
      @Autowired
      private WebApplicationContext wac;
  
      @Autowired
      private Filter springSecurityFilterChain;
  
      private MockMvc mockMvc;
  
      [...]
  
      @Before
      public void setup() {
          this.mockMvc = 
              MockMvcBuilders.webAppContextSetup(this.getWac())
              .addFilters(springSecurityFilterChain)
              .build();
      }
  
      [...]
  
  }
  </code></pre>
  
  <p>Then, my concrete test class inherits from AbstractResourceTest (from above) and it uses the following annotation on a @Test-enabled method:</p>
  
  <pre><code>@WithMockCustomUser(faps={"promotion_read"})
  </code></pre>
  
  <p>Tracing the code, I can confirm WithMockCustomUserSecurityContextFactory.createSecurityContext() is called and its return value is set in SecurityContextHolder.setContext() (through TestSecurityContextHolder.setContext()).</p>
  
  <p>So far, so good !</p>
  
  <p>However, later in the process, SecurityContextPersistenceFilter.doFilter() calls SecurityContextHolder.setContext() and this overwrites the context set by the test and I lose track of the mocked security context I prepared.</p>
  
  <p>security.xml:
      </p>
  
  <pre><code>&lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:security="http://www.springframework.org/schema/security"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
          http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
      "
  &gt;
  
      &lt;!-- HTTP security handling --&gt;
      &lt;security:http use-expressions="true"&gt;
  
          &lt;security:logout logout-url="/j_spring_security_logout" invalidate-session="true" logout-success-url="/login.jsp?loggedout=true" /&gt;
  
          &lt;security:custom-filter before="FIRST" ref="multiTenantRequestFilter" /&gt;
  
          &lt;!-- make sure following page are not secured --&gt;
  
          &lt;security:intercept-url pattern="/*/*/internal/**" access="hasIpAddress('127.0.0.1')" /&gt;
  
          &lt;!-- make sure everything else going through the security filter is secured --&gt;
  
          &lt;security:intercept-url pattern="/resources/**" access="hasRole('ROLE_USER')" requires-channel="any" /&gt;
  
          &lt;!-- supporting basic authentication for unattended connections (web services) --&gt;
  
          &lt;security:http-basic /&gt;
  
      &lt;/security:http&gt;
  
      &lt;!-- authentication strategy --&gt;
  
      &lt;security:authentication-manager alias="authManager"&gt;
          &lt;security:authentication-provider user-service-ref="userSecurityService"&gt;
              &lt;security:password-encoder ref="passwordEncoder" /&gt;
          &lt;/security:authentication-provider&gt;
      &lt;/security:authentication-manager&gt;
  
      &lt;!-- custom filter to intercept the tenant name from the login form --&gt;
  
      &lt;bean id="multiTenantRequestFilter" class="com.meicpg.ti.web.MultiTenantRequestFilter" /&gt;
  
  &lt;/beans&gt;
  </code></pre>
  
  <p>servlet.xml:
      </p>
  
  <pre><code>&lt;beans
      xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:security="http://www.springframework.org/schema/security"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:task="http://www.springframework.org/schema/task"
      xsi:schemaLocation="
          http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
          http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
          http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
      "
  &gt;
      &lt;mvc:annotation-driven&gt;
          &lt;!-- Content skipped for StackOverflow question --&gt;
      &lt;/mvc:annotation-driven&gt;
  
      &lt;context:annotation-config /&gt;
  
      &lt;bean id="annotationExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"&gt;&lt;/bean&gt;
  
      &lt;security:global-method-security pre-post-annotations="enabled"/&gt;
  
      &lt;aop:aspectj-autoproxy proxy-target-class="true"/&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p>How can I prevent this security context overwrite ? Does my security.xml contain an obvious flaw I missed ?</p>
  
  <p>PS: I skipped the other context configuration files as they seem irrelevant to the problem.</p>
  
  <p>Thanks in advance !</p>