Spring Security-OAuth2资源服务器测试

时间:2019-07-18 22:47:16

标签: java spring spring-boot spring-security spring-security-oauth2

使用@WebMvcTest和POST HTTP方法测试oauth2资源服务器时遇到一些问题。

我不发送csrf令牌时总是收到403状态代码,即使使用承载令牌时也不需要该令牌。

这是我要测试的POST方法。

@PostMapping("/message")
public String createMessage(@RequestBody String message) {
    return String.format("Message was created. Content: %s", message);
}

这是我的安全配置:

http.authorizeRequests(authorizeRequests -> authorizeRequests       
   .antMatchers("/message/**")
   .hasAuthority("SCOPE_message:read")
   .anyRequest().authenticated()
).oauth2ResourceServer(oauth2ResourceServer ->               
    oauth2ResourceServer
    .jwt(withDefaults())
);

我正在遵循spring-security样本中提供的测试。

以下测试应该通过,但失败,因为在请求中未发送csrf令牌。

mockMvc.perform(post("/message").content("Hello message")
    .with(jwt(jwt -> jwt.claim("scope", "message:read")))
    .andExpect(status().isOk())
    .andExpect(content().string(is("Message was created. Content: Hello message")));

当我将csrf令牌添加到请求中时,测试通过:

mockMvc.perform(post("/message").content("Hello message")
    .with(jwt(jwt -> jwt.claim("scope", "message:read")))
    .with(csrf()))
    .andExpect(status().isOk())
    .andExpect(content().string(is("Message was created. Content: Hello message")));

运行应用程序时,无需在POST请求中发送csrf令牌。

我已经分叉了Spring Security GitHub存储库,并且此测试失败的项目可在此link上找到。

我是否可以配置测试,因此不需要在POST请求中发送csrf令牌?

1 个答案:

答案 0 :(得分:2)

为了让CSRF过滤器检测到您正在使用JWT令牌,您将需要在JWT令牌中将其作为Authorization标头或请求参数。
您提到的测试具有模拟JwtDecoder,这意味着您可以使用任何字符串作为令牌并模拟解码后的值。
您的测试将变为:

Jwt jwt = Jwt.withTokenValue("token")
        .header("alg", "none")
        .claim("scope", "message:read")
        .build();
when(jwtDecoder.decode(anyString())).thenReturn(jwt);
mockMvc.perform(post("/message")
        .content("Hello message")
        .header("Authorization", "Bearer " + jwt.getTokenValue()))
        .andExpect(status().isOk())
        .andExpect(content().string(is("Message was created. Content: Hello message")));

如果您不模拟JwtDecoder,则需要检索有效的承载令牌并将其传递到Authorization标头中。