我想写一些依赖于Spring Security的单元测试。
例如,我有一些使用某些存储库并使用@PreAuthorize注释标记的服务方法。我可以用Mockito模拟存储库,没有问题。我也可以通过@WithSecurityContext注释来模拟安全上下文。但是当我运行test时,@ PereAuthorize注释被忽略了。当然,我可以使用@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();
}
答案 0 :(得分:2)
如果Spring Security代理您的组件(例如,服务bean),则只会遵守Spring Security的@PreAuthorize
注释。
实现这一目标的最简单方法是使用@Configuration
注释@EnableGlobalMethodSecurity(prePostEnabled = true)
类,将组件注册为bean(例如,通过组件扫描或@Bean
方法),并包括AuthenticationManager
设置。
然后,您可以使用@ContextConfiguration
创建一个集中的集成测试(没有Spring Boot测试支持),从ApplicationContext
类加载@Configuration
。您可以使用@Autowired
访问代理组件,并通过@PreAuthorize
安全检查支持建议。
您可能会发现此旧博客文章对于背景信息也很有用:https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/