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
相关产品推荐
相关产品推荐

