Авторизация и TestRestTemplate - PullRequest
1 голос
/ 18 июня 2020

Я использую форму входа Spring по умолчанию и REST API для других данных. Сеансы включены и используются.

Все URL-адреса (кроме формы /login) защищены.

Итак, как протестировать защищенные методы @RestController с помощью TestRestTemplate? (Я мог бы сделать дополнительный запрос к /api/login, чтобы получить Cookie, а затем сгенерировать и добавить Headers, но нет конечной точки REST для входа в систему, только аутентификация на основе формы).

Кроме того, аннотация @WithMockUser только для MockMvc (и не может использоваться с TestRestTemplate)?

1 Ответ

1 голос
/ 18 июня 2020

Шаги

  1. Репозиторий примера безопасности пружины клонирования git clone https://github.com/spring-guides/gs-securing-web.git
  2. Добавлен RestControllerIT
  3. Добавлен csrf().disable() в WebSecurityConfig. Этот тест не пройдет, если csrf включен
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RestControllerIT {

    @Autowired
    TestRestTemplate testRestTemplate;

    @LocalServerPort
    int localPort;

    @Test
    public void test(){
        String securedUrl = "http://localhost:" + localPort + "/hello";
        String loginUrl = "http://localhost:" + localPort + "/login";
        String username = "user";
        String password = "password";

        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
        form.set("username", username);
        form.set("password", password);
        ResponseEntity<String> loginResponse = testRestTemplate.postForEntity(
                loginUrl,
                new HttpEntity<>(form, new HttpHeaders()),
                String.class);
        String cookie = loginResponse.getHeaders().get("Set-Cookie").get(0);

        HttpHeaders headers = new HttpHeaders();
        headers.add("Cookie", cookie);
        ResponseEntity<String> responseFromSecuredEndPoint = testRestTemplate.exchange(securedUrl, HttpMethod.GET, new HttpEntity<>(headers), String.class);

        assertEquals(responseFromSecuredEndPoint.getStatusCode(), HttpStatus.OK);
        assertTrue(responseFromSecuredEndPoint.getBody().contains("Hello World!"));
    }
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
             User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}
...