如何使用 Spring Security @Secured 注解测试 Spring Boot @WebFluxTest

Posted

技术标签:

【中文标题】如何使用 Spring Security @Secured 注解测试 Spring Boot @WebFluxTest【英文标题】:How to test Spring Boot @WebFluxTest with Spring Security @Secured annotation 【发布时间】:2021-07-08 12:22:34 【问题描述】:

我在测试受 Spring Security 的 @Secured 注释保护的 Spring WebFlux 控制器时遇到了麻烦。这是我的控制器代码:

@RestController
@RequestMapping("/endpoint")
public class MyController 

    @GetMapping()
    @Secured("ADMIN")
    public Flux<MyOutputDto> getOutputDtos() 
        return myService.getOutputDtos();
    

这是我的测试代码:

@WebFluxTest(MyController.class)
class MyControllerTest 

    @Autowired
    WebTestClient webTestClient;

    @Test
    @WithApplicationUser(roles = "ADMIN")
    void should_work_fine() 
        webTestClient.get()
                .uri("/endpoint")
                .exchange()
                .expectStatus().isOk();
    

    @Test
    void should_return_401_unauthorized() 
        webTestClient.get()
                .uri("/endpoint")
                .exchange()
                .expectStatus().isUnauthorized();
    

    @Test
    @WithApplicationUser
    void should_return_403_forbidden() 
        webTestClient.get()
                .uri("/endpoint")
                .exchange()
                .expectStatus().isForbidden();
    

@WithApplicationUser 注释是一个自定义注释,它在具有提供角色的安全上下文中注入一个模拟身份验证对象。如果没有提供任何角色(如在第三个测试中),则默认为根本没有角色。

这里的问题是前两个测试工作正常,但第三个测试失败,返回 200 OK 而不是 403 Forbidden。我的第一个想法是 Spring Security 不处理 @Secured 注释,所以我关注了许多 Spring WebFlux/Spring Security 文档和在线文章,但没有一个有效。

有人对此有想法吗?提前致谢

【问题讨论】:

它是否适用于来自 org.springframework.security:spring-security-test 的 Spring 默认 @WithMockUser(roles = "ADMIN")? @DirkDeyne 不,同样的结果 【参考方案1】:

好的,所以我知道发生了什么。

首先,@Secured 注释似乎没有被 Spring Security 处理用于响应式应用程序(即 Spring WebFlux)。对于@EnableReactiveMethodSecurity,您必须使用@PreAuthorize 注释。

然后,我必须创建一个测试配置并将其导入我的测试,它就像一个魅力。

@TestConfiguration
@EnableReactiveMethodSecurity
public class WebFluxControllerSecurityTestConfig 

@WebFluxTest(MyController.class)
@Import(WebFluxControllerSecurityTestConfig.class)
class MyControllerTest 

  // Same tests


【讨论】:

以上是关于如何使用 Spring Security @Secured 注解测试 Spring Boot @WebFluxTest的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security sec:使用 Java Config 授权标签

Spring Security sec:授权抛出异常

如何在 Spring Security 的同一个请求中使用两个身份验证提供程序?

我在这里使用 Struts 2 和 Spring Security Integration

如何从 Spring Security 中的会话管理(超时/并发检查)中排除某些页面?

sec:authorize 对 Spring Security 不起作用