使用 JWT 和 PreAuthorized 与 Oauth 进行 Spring Boot 集成测试

问题描述 投票:0回答:1

目前我有一个使用 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 注释的控制器

我已经看过了这个,但仍然没有找到一个干净的方法来做到这一点,

谢谢

jwt integration-testing spring-security-oauth2 userdetailsservice oauth2resourceserver
1个回答
0
投票

我现在需要引入这个自定义 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]."));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.