Request Post-Processors

Per-Request Users and CSRF

SecurityMockMvcRequestPostProcessors set security details on a single request — handy when one test needs several users:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;

mvc.perform(get("/api/orders").with(user("asha").roles("CUSTOMER")))
   .andExpect(status().isOk());

mvc.perform(post("/api/cart/items").with(user("asha")).with(csrf())      // valid CSRF token
        .contentType(MediaType.APPLICATION_JSON).content("{\"productId\":7,\"quantity\":1}"))
   .andExpect(status().isCreated());

mvc.perform(post("/api/cart/items").with(user("asha")).with(csrf().useInvalidToken()))
   .andExpect(status().isForbidden());                                 // CSRF protection works

mvc.perform(get("/api/orders").with(httpBasic("[email protected]", "S3cret!pass")))
   .andExpect(status().isOk());

Form Login and Logout

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;

@Test
void sellerCanLogIn() throws Exception {
    mvc.perform(formLogin("/login").user("[email protected]").password("Correct-Horse-42"))
       .andExpect(authenticated().withUsername("[email protected]").withRoles("SELLER"))
       .andExpect(redirectedUrl("/seller/dashboard"));
}

@Test
void wrongPasswordStaysAnonymous() throws Exception {
    mvc.perform(formLogin("/login").user("[email protected]").password("nope"))
       .andExpect(unauthenticated())
       .andExpect(redirectedUrl("/login?error"));
}

@Test
void logoutWorks() throws Exception {
    mvc.perform(logout()).andExpect(redirectedUrl("/login?logout"));
}

Tip: Login tests that go through formLogin() or httpBasic() need a real UserDetailsService and PasswordEncoder in the context — use @SpringBootTest with a test database, or @Import a small in-memory user config.