gpt4 book ai didi

java - 在 Oauth2 安全(客户端凭据)资源服务器应用程序中为 WebFluxTest 获取 403 Forbidden Forbidden

转载 作者:行者123 更新时间:2023-12-01 13:45:22 26 4
gpt4 key购买 nike

我有一个响应式(Reactive)(Spring WebFlux)Web 应用程序,其中很少有 protected 资源的 REST API。(Oauth2)。要手动访问它们,我需要获取具有客户端凭据授予类型的授权 token 并在请求中使用该 token 。
现在,我需要编写可以通过 Spring 的 WebTestClient 进行调用来调用 API 的测试。我在尝试访问 API 时收到 403 禁止。编写测试用例时我哪里做错了。
以下是我的安全配置:

@EnableWebFluxSecurity
public class WebSecurityConfiguration {

@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeExchange()
.pathMatchers(ACTUATOR_ENDPOINT_PATTERN)
.permitAll()
.pathMatchers("/my/api/*")
.hasAuthority("SCOPE_myApi")
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
http.addFilterAfter(new SomeFilter(), SecurityWebFiltersOrder.AUTHORIZATION);

return http.build();
}

@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService) {

ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();

AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

return authorizedClientManager;
}

@Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
return WebClient.builder().filter(oauth).build();
}

}

注意:- 我需要这个 webclient bean,因为在那个过滤器(我添加到 SecurityWebFilterChain)中,我正在调用另一个 protected 资源/API,并且该 API 的响应正在 react 上下文中设置
我的应用程序 yaml:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: ${oidc-issuer-uri}
client:
provider:
myProvider:
issuer-uri: ${oidc-issuer-uri}
registration:
myProvider:
client-id: another-service-client
client-secret: ${another-service-clientSecret}
scope: anotherServiceScope
authorization-grant-type: client_credentials
我的 Controller :
@RestController
public class MyController {
@GetMapping(value = "/my/api/greet")
public Mono<String> greet() {
return Mono.subscriberContext()
.flatMap(context -> {
String someVal = context.get("MY_CONTEXT"); //This context is being set inside the filter 'SomeFilter'
//Use this someVal
return Mono.just("Hello World");
});

}
}
我的测试用例:
@RunWith(SpringRunner.class)
@WebFluxTest(controllers = {MyController.class})
@Import({WebSecurityConfiguration.class})
@WithMockUser
public class MyControllerTest {


@Autowired
private WebTestClient webTestClient;

@Test
public void test_greet() throws Exception {

webTestClient.mutateWith(csrf()).get()
.uri("/my/api/greet")
.exchange()
.expectStatus().isOk();
}

}

注意:- 我无法通过不使用我的 WebSecurityConfiguration 类来绕过。因为在 websecurityconfiguration 中添加的过滤器中设置了 react 上下文。

最佳答案

这里需要两件事:

  • 首先访问/my/api/greet,webTestClient 需要 SCOPE_myApi 并且由于这里不涉及“用户”,所以我们不需要 @WithMockUser
  •   @Test
    public void test_greet() {

    webTestClient
    .mutateWith(mockOidcLogin().authorities(new SimpleGrantedAuthority("SCOPE_myApi")))
    .get()
    .uri("/my/api/greet")
    .exchange()
    .expectStatus().isOk()
    .expectBody(String.class).isEqualTo("mockSasToken");
    }
  • 接下来我们需要一个wiremock服务器来模拟“另一个服务”的响应

  • 对于这个选项是使用 spring boot @AutoConfigureWireMock(port = 0) 自动启动一个wiremock服务器并在随机端口为我们关闭。
    接下来,我们在测试方法中 stub 对“另一个服务”和 Oauth2 token 端点的响应。
    最后,我们需要一个“测试” spring 配置文件和一个相应的 application-test.yaml,我们告诉 spring 使用线模端点来获取 token :
    spring:
    security:
    oauth2:
    resourceserver:
    jwt:
    jwk-set-uri: http://localhost:${wiremock.server.port}/.well-known/jwks_uri
    client:
    provider:
    myProvider:
    token-uri: http://localhost:${wiremock.server.port}/.well-known/token
    registration:
    myProvider:
    client-id: mockClient
    client-secret: mockSecret

    关于java - 在 Oauth2 安全(客户端凭据)资源服务器应用程序中为 WebFluxTest 获取 403 Forbidden Forbidden,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62602592/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com