如何将授权服务器不可用场景映射为HTTP 503状态码?
问题解答
一、是否应该将「授权服务器宕机」映射为HTTP 503状态码?
完全合理。HTTP 503(Service Unavailable)语义上表示服务暂时无法处理请求,授权服务器宕机属于依赖服务不可用的场景,而非用户认证失败(比如无效Token、过期Token这类场景才应该返回401 Unauthorized)。返回503能更准确地告知客户端问题根源,避免客户端误判为自身认证信息错误。
二、更优的统一异常处理方案(避免逻辑分散)
由于JWT解码在BearerTokenAuthenticationFilter中执行(属于Spring Security过滤器链,早于Spring MVC的DispatcherServlet),@ControllerAdvice无法直接捕获这类异常。要实现统一异常处理,核心思路是将Security链中的异常转发到Spring MVC的异常处理机制,让@ControllerAdvice接管所有异常逻辑。
方案实现步骤:
自定义
AuthenticationEntryPoint,将异常转发到Spring MVC的错误处理端点@Bean public AuthenticationEntryPoint authenticationEntryPoint() { return (request, response, authException) -> { // 将异常存入request属性,供后续MVC异常处理器获取 request.setAttribute("javax.servlet.error.exception", authException); // 转发到Spring MVC默认的错误处理路径(也可自定义路径) request.getRequestDispatcher("/error").forward(request, response); }; }在
@ControllerAdvice中统一处理所有认证相关异常@ControllerAdvice public class GlobalAuthenticationExceptionHandler { // 处理授权服务器宕机引发的AuthenticationServiceException @ExceptionHandler(AuthenticationServiceException.class) public ResponseEntity<ErrorResponse> handleAuthServiceUnavailable(AuthenticationServiceException ex) { ErrorResponse error = new ErrorResponse( HttpStatus.SERVICE_UNAVAILABLE.value(), "授权服务暂时不可用,请稍后重试" ); return new ResponseEntity<>(error, HttpStatus.SERVICE_UNAVAILABLE); } // 处理其他认证失败场景(无效Token、过期Token等) @ExceptionHandler(AuthenticationException.class) public ResponseEntity<ErrorResponse> handleAuthenticationFailure(AuthenticationException ex) { ErrorResponse error = new ErrorResponse( HttpStatus.UNAUTHORIZED.value(), ex.getMessage() ); return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED); } // 自定义错误响应体 public static class ErrorResponse { private int status; private String message; public ErrorResponse(int status, String message) { this.status = status; this.message = message; } // Getter方法(根据JSON序列化需求添加) public int getStatus() { return status; } public String getMessage() { return message; } } }保持SecurityFilterChain配置不变
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .oauth2ResourceServer(oauth2 -> oauth2 .authenticationEntryPoint(authenticationEntryPoint()) // 其他配置... ); return http.build(); }
方案优势:
- 所有异常处理逻辑集中在
@ControllerAdvice中,避免Security与MVC层面的逻辑分散 - 严格遵循HTTP语义,不同场景返回对应状态码
- 自定义错误响应体,可统一格式便于客户端解析
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

