tiefenauer
tiefenauer

Reputation: 809

Spring Boot integration test: Initialize security context

I have a microservice exposing a REST-API which is secured with OAuth2 using the default Spring Boot configuration in application.yml:

security:
  oauth2:
    client:
      client-id: ...
      client-secret: ...
      grant-type: ...
    resource:
      user-info-uri: ...
      token-info-uri: ...
      prefer-token-info: false

The API methods have the usual annotations. The user is authorized in a frontend, which sends authorized requests to the API by sending the token in the header (Authorization: Bearer ...).

The user details can then be read in the backend by injecting the Principal as an argument in the mapped controller methods, e.g.:

@CrossOrigin
@RestController
@RequestMapping("/foo")
@ContextConfiguration
public class MyController {

    @GetMapping("/all")
    public ResponseEntity<List<String>> sampleMethod(Principal user) { // <<- Principal SHOULD NOT BE NULL FOR INTEGRATION TEST
        // some code here
    }
}

This works well when running the real microservice. However when running integration tests with MockMVC the principal is always null:

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
class MyControllerIT {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldReturnOk() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/all"))
                .andExpect(status().isOk();
    }

}

What is an easy way to set up the @SpringBootTest integration test so the security context is pre-populated with some Principal under my control?

Upvotes: 1

Views: 679

Answers (2)

ch4mp
ch4mp

Reputation: 12564

There is a jwt post processors for MockMvc request builder. Sample here: https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials/resource-server_with_jwtauthenticationtoken

There is also a dedicated post processor for BearerTokenAuthentication if you are using introspection instead of JWT decoder.

PS In the répo linked above, you'll find annotations like @WithMockJwtAuth that I find more usable than MockMvc requests processors.

Upvotes: 0

grekier
grekier

Reputation: 3697

You can pass the user/principal like:

mockMvc.perform(MockMvcRequestBuilders.get("/all")).with(user("admin").password("pass").roles("USER","ADMIN")))

See https://docs.spring.io/spring-security/reference/servlet/test/mockmvc/authentication.html for all possibilities

Upvotes: 1

Related Questions