为什么我的测试在没有不记名令牌的情况下通过
Why my test passes without a bearer token
我有一个简单的 Spring 应用程序。但是我不明白为什么不需要不记名令牌就可以通过测试。
这是控制器:
...
@GetMapping
@PreAuthorize("hasAuthority('app-user')")
public ResponseEntity<List<FooDTO>> findAll(){
return ResponseEntity.ok(fooService.findAll());
}
安全配置:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@PropertySource("classpath:application-${env}.yml")
static class OAuth2SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
http.cors();
http.csrf().disable();
}
}
为了设置我正在使用的测试的安全配置:
@TestConfiguration
@Import({OAuth2SecurityConfigurerAdapter.class})
public class DefaultTestConfiguration {
}
所以我的测试 class 看起来像这样:
@AutoConfigureMockMvc
@ContextConfiguration(classes = {FooController.class})
@WebMvcTest
@ActiveProfiles("test")
@Import(DefaultTestConfiguration.class)
public class FooIntegrationTest {
@Test
@WithMockUser(authorities = "app-user")
public void findAllShouldReturnAList() throws Exception {
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/foos")
.accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andReturn();
assertThat(result.getResponse()).isNotNull();
}
}
如果我将测试中的 autority 更改为 'foo-user' 之类的内容,响应将按预期变为 403,因此我认为正在应用安全配置。
如果我使用 Postman 测试应用程序,运行 请求需要不记名令牌,但为什么在测试中不需要它?
@WithMockUser 注解不做认证。 (请注意,您甚至没有提供用户名。)
它使用 user/password 名称和密码创建一个新的默认用户,并且该用户已经使用 UsernamePasswordAuthenticationToken 进行了身份验证。
并且您在 @WithMockUser(authorities = "app-user") 注释中为这个默认 user/password 用户提供了权限作为“app-user”。
https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/test/context/support/WithMockUser.html
所以你运行你测试的用户有身份验证和授权。
未应用您的安全配置。
同样,@WithMockUser 使用具有安全默认值的 SecurityContextHolder.createEmptyContext() 创建新的空安全上下文。
https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/test/context/support/WithMockUser.html
当您使用 Postman 时,当然不会发生所有这些事情,您的真实用户必须使用普通的持有者令牌进行身份验证。
我有一个简单的 Spring 应用程序。但是我不明白为什么不需要不记名令牌就可以通过测试。
这是控制器:
...
@GetMapping
@PreAuthorize("hasAuthority('app-user')")
public ResponseEntity<List<FooDTO>> findAll(){
return ResponseEntity.ok(fooService.findAll());
}
安全配置:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@PropertySource("classpath:application-${env}.yml")
static class OAuth2SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
http.cors();
http.csrf().disable();
}
}
为了设置我正在使用的测试的安全配置:
@TestConfiguration
@Import({OAuth2SecurityConfigurerAdapter.class})
public class DefaultTestConfiguration {
}
所以我的测试 class 看起来像这样:
@AutoConfigureMockMvc
@ContextConfiguration(classes = {FooController.class})
@WebMvcTest
@ActiveProfiles("test")
@Import(DefaultTestConfiguration.class)
public class FooIntegrationTest {
@Test
@WithMockUser(authorities = "app-user")
public void findAllShouldReturnAList() throws Exception {
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/foos")
.accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andReturn();
assertThat(result.getResponse()).isNotNull();
}
}
如果我将测试中的 autority 更改为 'foo-user' 之类的内容,响应将按预期变为 403,因此我认为正在应用安全配置。
如果我使用 Postman 测试应用程序,运行 请求需要不记名令牌,但为什么在测试中不需要它?
@WithMockUser 注解不做认证。 (请注意,您甚至没有提供用户名。) 它使用 user/password 名称和密码创建一个新的默认用户,并且该用户已经使用 UsernamePasswordAuthenticationToken 进行了身份验证。 并且您在 @WithMockUser(authorities = "app-user") 注释中为这个默认 user/password 用户提供了权限作为“app-user”。 https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/test/context/support/WithMockUser.html
所以你运行你测试的用户有身份验证和授权。
未应用您的安全配置。 同样,@WithMockUser 使用具有安全默认值的 SecurityContextHolder.createEmptyContext() 创建新的空安全上下文。 https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/test/context/support/WithMockUser.html
当您使用 Postman 时,当然不会发生所有这些事情,您的真实用户必须使用普通的持有者令牌进行身份验证。