I'm implementing new Spring Authorization server (spring-security-oauth2-authorization-server version 1.0.0). I have created following two classes to handle exceptions:
public class RestExceptionTranslationFilter implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// Code to handle the exception
}
}
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
// Code to handle the exception
}
}
I have registered both of them like this:
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
...
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer.tokenEndpoint(tokenEndpoint ->
((OAuth2TokenEndpointConfigurer)tokenEndpoint).errorResponseHandler(new RestExceptionTranslationFilter())
);
...
http.exceptionHandling(exceptions ->
exceptions.authenticationEntryPoint(new RestAuthenticationEntryPoint()));
}
Now I'm able to handle the OAuth2AuthenticationException
exceptions and other exceptions and to return the response that my implementation requires. For example, this exception is handled correctly:
org.springframework.security.oauth2.core.OAuth2AuthenticationException: OAuth 2.0 Parameter: grant_type
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.throwError(OAuth2TokenEndpointFilter.java:260) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.doFilterInternal(OAuth2TokenEndpointFilter.java:159) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
But, what's confusing me, and I cant solve it, why the same OAuth2AuthenticationException
exception is not handled by this configuration in case when its thrown like this from ClientSecretAuthenticationProvider
:
org.springframework.security.oauth2.core.OAuth2AuthenticationException: Client authentication failed: client_id
at org.springframework.security.oauth2.server.authorization.authentication.ClientSecretAuthenticationProvider.throwInvalidClient(ClientSecretAuthenticationProvider.java:151) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.oauth2.server.authorization.authentication.ClientSecretAuthenticationProvider.authenticate(ClientSecretAuthenticationProvider.java:99) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
Is it possible to handle this exception and how as I would really like not to disclose the message "error": "invalid_client"
to the possible attackers?
Take a look at Configuring Client Authentication in the reference. It would be very similar to how you configured the tokenEndpoint()
:
authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.errorResponseHandler(new RestExceptionTranslationFilter())
);
Note: "TranslationFilter" is probably not the best name for an AuthenticationFailureHandler
, but is a minor detail.