Spring losing session authentication with TestRestTemplate

Viewed 684

I am running a test using Spring's TestRestTemplate to execute 2 api calls in sequence. My Test has this infrastucture:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

Api call 1:

  • GET
  • HttpSecurity allows this request always
  • @PreAuthorize("isAnonymous()")
  • Automatically logs in the user using these:

:

final Authentication myCustomAuthentication = ...MyCustomObjectForNewLogin)
eventPublisher.publishEvent(new AuthenticationSuccessEvent(myCustomAuthentication));
SecurityContextHolder.getContext().setAuthentication(myCustomAuthentication);
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getSession(true).setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());

Api call 2: - POST - @PreAuthorize("hasAuthority('MyAuthorityThatHeAlwaysHasWhenLoggedIn')")

The issue is: On the second call I always get a 401 Unauthorized. I have traced this down to the following: in the spring class AnonymousAuthenticationFilter#doFilter:96 This is happening:

if (SecurityContextHolder.getContext().getAuthentication() == null) {
            SecurityContextHolder.getContext().setAuthentication(
                    createAuthentication((HttpServletRequest) req));

            if (logger.isDebugEnabled()) {
                logger.debug("Populated SecurityContextHolder with anonymous token: '"
                        + SecurityContextHolder.getContext().getAuthentication() + "'");
            }
        }

for some reason it looks like the context lost the authentication and is hence being repopulated as an anonymous user. I read that this value is a ThreadLocal in some cases which is why i am also setting the attribute in the session so it can be re-loaded however it seems to not be reloaded. How can i either force it to be reloaded or inject the value into that holder. (Note this series of api calls works when done through postman. Only fails in the test).

I am executing the calls as follows:

@Autowired
private TestRestTemplate rest;

rest.getForEntity(UriComponentsBuilder.fromPath("/api1/").queryParam("myparm", "val").build(true).toUri(), String.class));
rest.postForEntity("/api2/", new HttpEntity<>(myExpectedObject, state), String.class)
0 Answers
Related