1

我想编写某种依赖于 Spring Security 的单元测试。

例如,我有一些服务方法,它使用一些存储库并用 @PreAuthorize 注释标记。存储库我可以用 Mockito 模拟,没有问题。我也可以通过@WithSecurityContext注释来模拟安全上下文。但是当我运行测试时,@PreAuthorize 注释被忽略了。当然,我可以使用 @SpringBootTest 注释作为集成测试运行该测试,在这种情况下,安全上下文已启动,但这种方式既繁重又缓慢。

有没有办法在引发 Spring Security Context 的情况下运行单元测试?

更新

做了一个这样的测试的例子。感谢@Sam Brannen 给出正确的方向。

@ActiveProfiles("method-security-test")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ExampleService.class, ExampleServiceTest.MethodSecurityConfiguration.class})
public class ExampleServiceTest {

    private ExampleService service;

    @Autowired
    public void setService(ExampleService service) {
        this.service = service;
    }

    @Test
    @WithMockUser(username = "john_doe")
    public void testAuthenticated() {
        String actualMessage = service.example();
        Assert.assertEquals("Message of john_doe", actualMessage);
    }

    @Test(expected = AuthenticationException.class)
    public void testNotAuthenticated() {
        service.example();
        Assert.fail();
    }

    @TestConfiguration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    static class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
    }
}

@Service
class ExampleService {
    @PreAuthorize("isAuthenticated()")
    String example() {
        Principal principal = SecurityContextHolder.getContext().getAuthentication();
        return "Message of " + principal.getName();
    }
4

1 回答 1

3

@PreAuthorize只有当 Spring Security 代理您的组件(例如,服务 bean)时,才会使用 Spring Security的注释。

实现这一点的最简单方法是使用 注释一个@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true),将您的组件注册为 bean(例如,通过组件扫描或@Bean方法),并包括您的AuthenticationManager设置。

然后,您可以使用(没有 Spring Boot 测试支持)从您的类@ContextConfiguration中加载一个集中的集成测试。您可以使用它来访问您的代理组件,安全检查支持会建议您访问代理组件。ApplicationContext@Configuration@Autowired@PreAuthorize

您可能会发现这篇旧博客文章对背景信息也很有用:https ://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/

于 2018-05-08T12:18:38.460 回答