繁体   English   中英

Spring security - oauth2 资源服务器测试

[英]Spring security - oauth2 resource server tests

使用@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 存储库,这个测试失败的项目可以在这个链接上找到。

有没有办法让我配置我的测试,这样我就不需要在 POST 请求中发送 csrf 令牌?

为了让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标头中。

首先使用 Bearer 访问令牌,您可以禁用会话(STATELESS 会话管理),并因此禁用 CSRF 保护(CSRF 攻击向量是会话)。

其次是.csrf() MockMvc 请求后处理器,如果你想保持让步(和 CSRF 保护),它会模拟 CSRF 令牌。

最后, jwt()请求后处理器所做的是使用JwtAuthenticationToken实例直接配置安全上下文,而不是创建有效的 JWT 令牌集作为 Bearer 访问令牌。 使用 MockMvc,授权 header 不会被解码或转换为身份验证实例。 => 在 MockMvc 请求执行之前您应该设置的是权限,而不是 scope 声明:

.with(jwt(jwt -> jwt.authorities(List.of(new SimpleGrantedAuthority("SCOPE_message:read")))))

请注意,您也可以简单地用以下内容装饰您的测试 function:

@WithMockJwtAuth("SCOPE_message:read")

这个库我维护

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM