【问题标题】:How to handle OAuth webclient exceptions如何处理 OAuth webclient 异常
【发布时间】:2021-03-12 21:40:29
【问题描述】:

我对 Spring 很陌生,并且在通过 OAUTH 对服务器进行身份验证时一直试图捕获未经授权的异常。我不明白为什么方法 handleResponseError() 没有捕捉到异常。

我得到的堆栈跟踪是:

org.springframework.security.oauth2.client.ClientAuthorizationException: [invalid_client] Client authentication failed
    at org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider.lambda$authorize$0(ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java:82)
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Request to GET https://localhost:8181/catalog/NL/brands?language_code=nl [DefaultWebClient]
Stack trace:
        at org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider.lambda$authorize$0(ClientCredentialsReactiveOAuth2AuthorizedClientProvider.java:82)
        at reactor.core.publisher.Mono.lambda$onErrorMap$29(Mono.java:3272)
        at reactor.core.publisher.Mono.lambda$onErrorResume$31(Mono.java:3362)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:88)
        at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onError(FluxHide.java:132)
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:185)
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:251)
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:134)
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:134)
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:135)
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73)
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:144)

对服务器进行身份验证的代码:

  @Bean
  public WebClient myClient() {
    InMemoryReactiveClientRegistrationRepository clientRegistryRepo = new InMemoryReactiveClientRegistrationRepository(getClientRegistration());
    InMemoryReactiveOAuth2AuthorizedClientService clientService = new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistryRepo);
    AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistryRepo, clientService);
    ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);

    oauthFilter.setDefaultClientRegistrationId(OAUTH_PROVIDER_NAME);

    return WebClient.builder()
        .clientConnector(new JettyClientHttpConnector(createHttpClient()))
        .exchangeStrategies(getMaxMessageInMemorySize(maxInMemorySize))
        .baseUrl(baseURL)
        .filter(oauthFilter)
        .filter(handleResponseError())
        .build();
  }

  private static ExchangeFilterFunction handleResponseError() {
    return ExchangeFilterFunction.ofResponseProcessor(
        response -> response.statusCode().isError() ?
            response.bodyToMono(String.class)
                .flatMap(errorBody -> Mono.error(new MyUnAuthorizedRequestException(response.statusCode().name(), errorBody, ""))) :
            Mono.just(response));
  }

我看过各种例子:

我使用@ControllerAdvice 捕获所有其他异常。这是处理这个问题的正确方法吗?

【问题讨论】:

    标签: java spring exception oauth authorization


    【解决方案1】:

    我找到了解决办法:

     .... omitted
     ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter = new 
     ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
        oauthFilter.setDefaultClientRegistrationId(OAUTH_PROVIDER_NAME);
    
        return WebClient.builder()
            .clientConnector(new JettyClientHttpConnector(createHttpClient()))
            .exchangeStrategies(getMaxMessageInMemorySize(maxInMemorySize))
            .baseUrl(baseURL)
            .filter(oauthFilter)
            .build();
      }
    
    
      private ReactiveOAuth2AuthorizationFailureHandler getReactiveOAuth2AuthorizationFailureHandler() {
        final ReactiveOAuth2AuthorizationFailureHandler reactiveOAuth2AuthorizationFailureHandler = (authorizationException, principal, attributes) -> {
          if (authorizationException instanceof ClientAuthorizationException) {
            ClientAuthorizationException clientAuthorizationException = (ClientAuthorizationException)authorizationException;
            return Mono.error(new MyUnAuthorizedRequestException("401","Could not authorize client", clientAuthorizationException.getMessage()));
          } else {
            return Mono.empty();
          }
        };
        return reactiveOAuth2AuthorizationFailureHandler;
      }
    

    【讨论】:

      猜你喜欢
      • 2019-03-20
      • 2011-05-23
      • 2019-11-07
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多