The error format of spring security oauth conforms with the OAuth spec and looks like this.
{
"error":"insufficient_scope",
"error_description":"Insufficient scope for this resource",
"scope":"do.something"
}
Especially on a resource server I find it a bit strange to get a different error format for authentication issues. So I would like to change the way this exception is rendered.
The documentation says
Error handling in an Authorization Server uses standard Spring MVC features, namely @ExceptionHandler methods
So I tried something like this to customize the format of the error:
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyErrorHandler {
@ExceptionHandler(value = {InsufficientScopeException.class})
ResponseEntity<MyErrorRepresentation> handle(RuntimeException ex, HttpServletRequest request) {
return errorResponse(HttpStatus.FORBIDDEN,
MyErrorRepresentation.builder()
.errorId("insufficient.scope")
.build(),
request);
}
}
But this does not work.
Looking at the code, all the error rendering seems to be done in DefaultWebResponseExceptionTranslator#handleOAuth2Exception
. But implementing a custom WebResponseExceptionTranslator
would not allow changing the format.
Any hints?
First of all,some knowledge for Spring Security OAuth2.
Then, custom OAuth2Exceptions should consider for AuthorizationServer and ResourceServer.
This is configuration
MyWebResponseExceptionTranslator is translate the exception to ourOAuthException and we custom ourOAuthException serializer by jackson, which way is same by default the OAuth2 use.
other custom handle class stuff
for custom ResourceServer exception
Spring Boot version: 2.2.5
You really don't have to write that much code. All you need to do create a custom
AuthenticationEntryPoint
by extending OAuth2AuthenticationEntryPoint, override enhanceResponse method of it and register it via Resource Server configuration.First part:
Second part:
Keep in mind that according to spec 401 response must send
WWW-Authenticate
header. The enhanceResponse that we override sends that header. Take a look at the implementation and send that header if you return 401.I found a similar question with answers that really helped my solving this - Handle spring security authentication exceptions with @ExceptionHandler
But my question is specifically about
spring-security-oauth2
- so I think it is still worth stating the answer specific tospring-security-oauth2
. My solution was picked from different answers to the question mentioned above.My samples work for
spring-security-oauth2 2.0.13
So the solution for me to achieve a different custom error structure for oauth2 errors on resource server resources was to register a custom
OAuth2AuthenticationEntryPoint
andOAuth2AccessDeniedHandler
that I register using aResourceServerConfigurerAdapter
. It is worth mentioning that this is only changing the format for ResourceServer endpoints - and not the AuthorizationServer endpoints like the TokenEndpoint.I could not reuse the functionality in
OAuth2AuthenticationEntryPoint
andOAuth2AccessDeniedHandler
because the relevant methods translate the exception and flush it in the same method. So I needed to copy some code: