目前我有一个使用 spring security 和 oauth2 ResourceServer 的安全配置。使用 JWT 令牌一切正常,这是我的安全过滤器链,如下所示:
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and().cors()
.and().csrf()
.and().oauth2ResourceServer().jwt();
我现在需要引入这个自定义 userDetailsService bean,以便将 preAuthorized 注释与自定义角色和权限一起使用:
@Bean
public UserDetailsService userDetailsService(IIUserService iiUserService) {
return new CustomUserDetailsService(new IIUserServiceFake());
}
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) {
//here I need to go to another micro-service to retrive the user roles/privileges and build a UserDetails Object
}
假设我有这个端点:
@GetMapping("/custom")
@PreAuthorize( "hasRole('ROLE_ADMIN')")
public String getData(){
return "I was able to see this endpoint";
}
我的集成测试如下所示:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class ControllerTest {
@LocalServerPort
private int serverPort;
@Autowired
private TestRestTemplate testRestTemplate;
@Test
public void entitlementTest() {
String uri = UriComponentsBuilder.fromHttpUrl("http://localhost").port(serverPort).path("/custom")
.build().toUriString();
ResponseEntity<String> forEntity = testRestTemplate.getForEntity(uri, String.class);
assertEquals(200, forEntity.getStatusCodeValue());
}
}
但现在我希望能够通过自定义引入角色/权限UserDetailsService 这里有几个问题: 1.- 如何模拟 JWT 资源服务器集成,以便在测试期间启用安全性,请求看起来已通过身份验证。 2.- 使用 UserDetailsService 自定义实现,我如何告诉 spring 要使用哪个字段,因为在我的情况下,我有一个来自令牌的自定义字段,该字段不称为“用户名”,可以说它称为“custom_user_name”。
基本上我希望能够使用 SpringBootTest 测试使用 JWT 令牌身份验证和 PreAuthorized 注释的控制器
我已经看过了这个,但仍然没有找到一个干净的方法来做到这一点,
谢谢
我现在需要引入这个自定义 userDetailsService bean,以便将 preAuthorized 注释与自定义角色和权限一起使用
您需要的是阅读手册和
Converter<Jwt, AbstractAuthenticationToken>
bean(例如具有正确配置或您自己的实现的JwtAuthenticationConverter
)。
在您的测试中,如果您使用
MockMvc
而不是 TestRestTemplate
,那么您可以使用 SecurityMockMvcRequestPostProcessors.jwt()
为您设置安全上下文(无需启动并运行授权服务器)。你也可以看看我写的这个lib,它提供了类似于@WithMockUser
的测试注释,但是针对OAuth2。集成测试示例取自there:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
class SampleApiIntegrationTest {
@Autowired
MockMvc api;
@Test
void givenRequestIsAnonymous_whenGetGreet_thenUnauthorized() throws Exception {
api.perform(get("/greet")).andExpect(status().isUnauthorized());
}
@Test
@WithJwt("ch4mp.json")
void givenUserIsCh4mpy_whenGetGreet_thenOk() throws Exception {
api.perform(get("/greet")).andExpect(content().string("Hello ch4mp! You are granted with [USER_ROLES_EDITOR, ROLE_AUTHORIZED_PERSONNEL]."));
}
}