在使用@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())
);我正在遵循弹簧-安全样本中提供的测试。
下面的测试应该通过,但失败了,因为在请求中没有发送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令牌。
我已经分叉了Security存储库,这个失败测试的项目可以在这个链接上使用。
是否有一种方法来配置我的测试,这样我就不需要在POST请求中发送csrf令牌了?
发布于 2019-07-19 16:48:56
为了让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头中。
https://stackoverflow.com/questions/57103518
复制相似问题