0

My SecurityConfiguration is configured as follows:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and()
            .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
            .authorizeRequests()
            .antMatchers("/api/auth", "/api/auth/**", "/api/oauth2/**").permitAll()
            .anyRequest().authenticated().and()
            .oauth2Login()
            //
}

I am testing my custom authentication POST endpoints /api/auth/login and /api/auth/register. The application runs fine and I am currently writing unit tests for them retro-actively. In my Controller unit test I have the following:

@WebMvcTest(AuthenticationController.class)
@ContextConfiguration(classes = {AuthenticationController.class})
class AuthenticationControllerTest {

@Test
void register() throws Exception {
    mockMvc.perform(post(BASE_PATH + "/register")
        .content(...) // POST body
        .with(csrf()))
        .andExpect(status().isOk());
}

This returns HTTP 401 (Unauthorized) instead of the expected HTTP 200. But if I add @WithMockUser (without any parameters) to the test method, then it does return 200. Why is a mock user required since I am not requiring authentication on the /api/auth endpoint? To be sure, I tried setting /api/auth/** in the SecurityConfiguration but the same issue remains. I have not implemented anything related to authorization yet, so roles are not an issue.

EDIT: It is worth noting that I tried setting .anyRequest().permitAll() as well, essentially saying that none of my endpoints require authentication, but the same problem occurs.

EDIT2: Updated test snippet and I use the following dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
Babyburger
  • 1,730
  • 3
  • 19
  • 32
  • can you please add your whole test to see how and which parts you bootstrap during the test execution? Please also add your `pom.xml` or provide more information if you use the Spring Boot Starter for Security or _only_ Spring Security – rieckpil Mar 20 '20 at 05:25
  • @rieckpil I added the information you requested to my question – Babyburger Mar 20 '20 at 08:07

1 Answers1

1

From this post SpringBoot @WebMvcTest security issue I learned that the SecurityConfiguration is not imported by default. So that explains why modifying the configuration has no influence. If the SecurityConfiguration should be loaded I need to add @Import(SecurityConfiguration.class) and provide the bean dependencies it seems.

I believe it is better suited for e2e tests, so I am not adding it to my unit test.

An alternative to simply adding @WithMockUser to every test method is to add @AutoConfigureMockMvc(addFilters = false) to the class. This will disable the security filter.

Babyburger
  • 1,730
  • 3
  • 19
  • 32