OAuth2AuthorizationRequestRedirectFilter传入不存在的客户端注册ID返回500错误的疑问及优化方案咨询
Let’s break down your questions one by one using the provided Spring Security code snippet:
1. Should this scenario return a 404 error instead of 500?
Absolutely. From RESTful API design principles, when a client requests an OAuth2 registration that doesn’t exist (like not-existed-registration), this is a client-side error—the requested registration resource simply isn’t available on the server. Returning 404 Not Found aligns with HTTP semantics, clearly communicating that the specified registration ID doesn’t exist. The current 500 response is misleading because it implies a server-side failure, which isn’t the case here.
2. How to change the response code from 500 to 400 (or 404)?
The fix hinges on distinguishing between different exception types in the error handling logic. Here’s how to adjust the code:
First, note that Spring Security typically throws ClientRegistrationNotFoundException when a requested registration can’t be found. Modify the unsuccessfulRedirectForAuthorization method to return the appropriate status code based on the exception type:
private void unsuccessfulRedirectForAuthorization(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { this.logger.error(LogMessage.format("Authorization Request failed: %s", ex, ex)); // Handle missing registration specifically if (ex instanceof ClientRegistrationNotFoundException) { // Return 404 to indicate the registration resource doesn't exist response.sendError(HttpStatus.NOT_FOUND.value(), HttpStatus.NOT_FOUND.getReasonPhrase()); // OR return 400 if you classify this as a bad request parameter // response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid registration ID"); } else { // Fallback to 500 for genuine server-side errors response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); } }
Alternatively, you could handle this earlier in the try block to avoid the generic error handler entirely:
try { OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request); if (authorizationRequest != null) { this.sendRedirectForAuthorization(request, response, authorizationRequest); return; } // If resolve returns null (some implementations use this instead of throwing) response.sendError(HttpStatus.NOT_FOUND.value(), "Requested OAuth2 registration not found"); return; } catch (ClientRegistrationNotFoundException ex) { response.sendError(HttpStatus.NOT_FOUND.value(), ex.getMessage()); return; } catch (Exception ex) { this.unsuccessfulRedirectForAuthorization(request, response, ex); return; }
3. Why does it return a 500 error?
The core issue is the generic error handling in the provided code. The unsuccessfulRedirectForAuthorization method treats every exception as an internal server error—it doesn’t differentiate between client mistakes (like requesting a non-existent registration) and actual server failures (e.g., database errors, runtime crashes).
When you call /oauth2/authorization/not-existed-registration, the authorizationRequestResolver.resolve(request) method throws an exception (usually ClientRegistrationNotFoundException). This gets caught by the catch-all Exception block, which triggers unsuccessfulRedirectForAuthorization—and that method blindly sends a 500 status code, regardless of why the exception occurred.
内容的提问来源于stack exchange,提问作者Holm

