Reputation: 5826
Here is my setup:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup", "/health").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.permitAll()
...
Test class:
@ExtendWith(SpringExtension.class)
@WebMvcTest
@WithMockUser
class ApiControllerTest {
...
@WithMockUser
works fine with below GET:
mockMvc.perform(get("/api/book/{id}", id))
.andExpect(status().isOk())
...
but not with POST:
mockMvc.perform(post("/api/book")
.contentType(MediaType.APPLICATION_JSON)
.content(payload))
.andExpect(status().isCreated())
...
When I look into the logs for MockHttpServletResponse, I notice the response is giving a redirect to login page, as follows:
MockHttpServletResponse:
Status = 302
Error message = null
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY", Location:"/login"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = /login
Cookies = []
I know that @WithMockUser
provides good amount of defaults for mocking user authentication. Why it is not working for stateful API request?
Upvotes: 3
Views: 2151
Reputation: 6936
By default, Spring Security protects you against Cross-site request forgery.
You have to actively disable it in your configuration if you don't want it.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
...
Luckily you did not, it is not safe to do so.
But as a consequence, you need to provide a csrf-token every time you do a POST
, so also in your tests!
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
...
mockMvc.perform(post("/api/book")
.with(csrf()) // <--- missing in your test
.contentType(MediaType.APPLICATION_JSON)
.content(payload))
.andExpect(status().isCreated());
Now your test should work.
Upvotes: 10