You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot OAuth2认证端点不可用时抛出自定义异常的方案

解决方案

方案1:局部捕获WebClient调用链中的授权异常

直接在WebClient调用链末尾添加onErrorResume操作符,捕获ClientAuthorizationException并转换为自定义异常。修改现有服务层代码:

webClient.get()
    .uri(finalURL)
    .accept(MediaType.APPLICATION_JSON)
    .exchangeToMono(clientResponse -> {
        switch (clientResponse.rawStatusCode()) {
            case OK:
                return clientResponse.bodyToMono(Resource.class);
            case NOT_FOUND:
                throw new ResourceNotFoundException(id);
            case INTERNAL_SERVER_ERROR:
                throw new InternalServerErrorException();
            default:
                return Mono.empty();
        }
    })
    // 捕获授权异常并转换为自定义异常
    .onErrorResume(ClientAuthorizationException.class, ex -> {
        // 可根据异常细节进一步判断是否为认证端点404场景
        return Mono.error(new AuthEndpointUnavailableException("认证服务不可用"));
    })

该方案适合单个WebClient请求的局部异常处理,灵活性高。

方案2:全局配置授权管理器的异常处理

通过自定义ReactiveOAuth2AuthorizedClientManager的授权失败处理器,全局处理所有使用该WebClient的授权异常。修改OAuthClientConfiguration中的webClient Bean:

@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {
    InMemoryReactiveOAuth2AuthorizedClientService clientService = new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrations);
    AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = 
        new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrations, clientService);
    
    // 设置授权失败的自定义处理逻辑
    authorizedClientManager.setAuthorizationFailureHandler((context, ex) -> {
        if (ex instanceof ClientAuthorizationException) {
            return Mono.error(new AuthEndpointUnavailableException("认证端点不可用"));
        }
        return Mono.error(ex);
    });

    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = 
        new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
    oauth.setDefaultClientRegistrationId("okta");
    return WebClient.builder()
            .filter(oauth)
            .build();
}

该方案会对所有使用此WebClient的请求生效,适合全局统一处理授权环节异常。

方案3:全局控制器异常处理器

使用@ControllerAdvice定义全局异常处理器,统一捕获并处理ClientAuthorizationException:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ClientAuthorizationException.class)
    public ResponseEntity<ErrorResponse> handleAuthException(ClientAuthorizationException ex) {
        ErrorResponse error = new ErrorResponse("AUTH_SERVICE_UNAVAILABLE", "认证服务暂时无法访问");
        return new ResponseEntity<>(error, HttpStatus.SERVICE_UNAVAILABLE);
    }

    // 自定义错误响应实体
    static class ErrorResponse {
        private String code;
        private String message;

        public ErrorResponse(String code, String message) {
            this.code = code;
            this.message = message;
        }

        // Getter方法
        public String getCode() {
            return code;
        }

        public String getMessage() {
            return message;
        }
    }
}

该方案覆盖所有控制器层的异常处理,不仅限于WebClient的授权异常,适合统一规范接口错误响应格式。


内容的提问来源于stack exchange,提问作者Riggster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:02:03