有没有办法在 Spring 启动测试中只启动安全上下文?
Is there a way to up only security context in Spring Boot tests?
我想编写某种依赖于 Spring 安全性的单元测试。
例如,我有一些服务方法使用了一些存储库并标有@PreAuthorize 注释。存储库我可以用 Mockito 模拟,没有问题。我也可以通过 @WithSecurityContext 注释来模拟安全上下文。但是当我 运行 测试时,@PreAuthorize 注释被忽略了。当然,我可以 运行 使用 @SpringBootTest 注释进行测试作为集成测试,在这种情况下,安全上下文已启动,但这种方式既繁重又缓慢。
有没有办法 运行 仅 Spring 引发安全上下文的单元测试?
更新
做了一个这样的测试的例子。感谢@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();
}
来自 Spring 安全性的 @PreAuthorize
注释只有在 Spring 安全性代理您的组件(例如,服务 bean)时才会受到尊重。
实现这一目标的最简单方法是使用 @EnableGlobalMethodSecurity(prePostEnabled = true)
注释 @Configuration
class,将您的组件注册为 bean(例如,通过组件扫描或 @Bean
方法),并包括您的 AuthenticationManager
设置。
然后您可以使用 @ContextConfiguration
(没有 Spring 引导测试支持)创建一个集中的集成测试,以从您的 @Configuration
class 加载 ApplicationContext
.您可以使用 @Autowired
来访问您的代理组件,这将通过 @PreAuthorize
安全检查支持得到建议。
您可能会发现这个旧博客 post 对于背景信息也很有用:https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/
我想编写某种依赖于 Spring 安全性的单元测试。
例如,我有一些服务方法使用了一些存储库并标有@PreAuthorize 注释。存储库我可以用 Mockito 模拟,没有问题。我也可以通过 @WithSecurityContext 注释来模拟安全上下文。但是当我 运行 测试时,@PreAuthorize 注释被忽略了。当然,我可以 运行 使用 @SpringBootTest 注释进行测试作为集成测试,在这种情况下,安全上下文已启动,但这种方式既繁重又缓慢。
有没有办法 运行 仅 Spring 引发安全上下文的单元测试?
更新
做了一个这样的测试的例子。感谢@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();
}
来自 Spring 安全性的 @PreAuthorize
注释只有在 Spring 安全性代理您的组件(例如,服务 bean)时才会受到尊重。
实现这一目标的最简单方法是使用 @EnableGlobalMethodSecurity(prePostEnabled = true)
注释 @Configuration
class,将您的组件注册为 bean(例如,通过组件扫描或 @Bean
方法),并包括您的 AuthenticationManager
设置。
然后您可以使用 @ContextConfiguration
(没有 Spring 引导测试支持)创建一个集中的集成测试,以从您的 @Configuration
class 加载 ApplicationContext
.您可以使用 @Autowired
来访问您的代理组件,这将通过 @PreAuthorize
安全检查支持得到建议。
您可能会发现这个旧博客 post 对于背景信息也很有用:https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/