Spring Security @WithMockUser, похоже, не работает с глаголами, изменяющими состояние (post, put ..) - PullRequest
0 голосов
/ 10 ноября 2019

Вот мои настройки:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/signup", "/health").permitAll()
            .anyRequest().authenticated().and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
...

Тестовый класс:

@ExtendWith(SpringExtension.class)
@WebMvcTest
@WithMockUser
class ApiControllerTest {
    ...

@WithMockUser отлично работает с ниже GET:

mockMvc.perform(get("/api/book/{id}", id))
        .andExpect(status().isOk())
...

, но не сPOST:

mockMvc.perform(post("/api/book")
        .contentType(MediaType.APPLICATION_JSON)
        .content(payload))
        .andExpect(status().isCreated())
...

Когда я просматриваю логи для MockHttpServletResponse, я замечаю, что ответ дает перенаправление на страницу входа, как показано ниже:

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 = []

Я знаю, что @WithMockUserобеспечивает хорошее количество значений по умолчанию для ложной аутентификации пользователя. Почему он не работает для запроса API с отслеживанием состояния?

1 Ответ

0 голосов
/ 10 ноября 2019

По умолчанию Spring Security защищает вас от подделки межсайтовых запросов.

Вы должны активно отключить его в своей конфигурации, если он вам не нужен.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        ...

К счастьюВы не сделали этого, это небезопасно.

Но, как следствие, вам необходимо предоставлять токен csrf каждый раз, когда вы делаете POST, так же как и в ваших тестах!


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());

Теперь ваш тест должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...