授权和 TestRestTemplate

Authorization and TestRestTemplate

我正在使用默认 Spring 登录表单和 REST API 其他数据。会话已启用并已使用。

所有网址(/login 表单除外)都受到保护。

那么如何使用TestRestTemplate测试受保护的@RestController方法呢? (我可以向 /api/login 发出额外请求以获取 Cookie,然后生成并添加 Headers,但是没有用于登录的 REST 端点,只有基于表单的身份验证)。

此外,@WithMockUser 注释是否仅适用于 MockMvc(不能与 TestRestTemplate 一起使用)?

步骤

  1. 克隆 spring 安全示例存储库 git clone https://github.com/spring-guides/gs-securing-web.git
  2. 添加了 RestControllerIT
  3. 已将 csrf().disable() 添加到 WebSecurityConfig。如果启用 csrf
  4. ,此测试将不会通过
@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);
    }
}