Skip to content

Commit 4016465

Browse files
author
Dmitriy Dubson
committed
Add reusable OAuth2ErrorAuthenticationFailureHandler
Related gh-1369
1 parent 1ed0b3a commit 4016465

File tree

7 files changed

+160
-60
lines changed

7 files changed

+160
-60
lines changed

docs/modules/ROOT/pages/protocol-endpoints.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
167167
* `*AuthenticationConverter*` -- An `OAuth2DeviceAuthorizationRequestAuthenticationConverter`.
168168
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2DeviceAuthorizationRequestAuthenticationProvider`.
169169
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2DeviceAuthorizationRequestAuthenticationToken` and returns the `OAuth2DeviceAuthorizationResponse`.
170-
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
170+
* `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler` instance that handles the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
171171

172172
[[oauth2-device-verification-endpoint]]
173173
== OAuth2 Device Verification Endpoint
@@ -264,7 +264,7 @@ The supported https://datatracker.ietf.org/doc/html/rfc6749#section-1.3[authoriz
264264
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeAuthenticationConverter`, `OAuth2RefreshTokenAuthenticationConverter`, `OAuth2ClientCredentialsAuthenticationConverter`, and `OAuth2DeviceCodeAuthenticationConverter`.
265265
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2AuthorizationCodeAuthenticationProvider`, `OAuth2RefreshTokenAuthenticationProvider`, `OAuth2ClientCredentialsAuthenticationProvider`, and `OAuth2DeviceCodeAuthenticationProvider`.
266266
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an `OAuth2AccessTokenAuthenticationToken` and returns the `OAuth2AccessTokenResponse`.
267-
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
267+
* `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler` instance that handles the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
268268

269269
[[oauth2-token-introspection-endpoint]]
270270
== OAuth2 Token Introspection Endpoint
@@ -311,7 +311,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
311311
* `*AuthenticationConverter*` -- An `OAuth2TokenIntrospectionAuthenticationConverter`.
312312
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenIntrospectionAuthenticationProvider`.
313313
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenIntrospectionAuthenticationToken` and returns the `OAuth2TokenIntrospection` response.
314-
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
314+
* `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler` instance that handles the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
315315

316316
[[oauth2-token-revocation-endpoint]]
317317
== OAuth2 Token Revocation Endpoint
@@ -358,7 +358,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
358358
* `*AuthenticationConverter*` -- An `OAuth2TokenRevocationAuthenticationConverter`.
359359
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenRevocationAuthenticationProvider`.
360360
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenRevocationAuthenticationToken` and returns the OAuth2 revocation response.
361-
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
361+
* `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler` instance that handles the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
362362

363363
[[oauth2-authorization-server-metadata-endpoint]]
364364
== OAuth2 Authorization Server Metadata Endpoint

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2DeviceAuthorizationEndpointFilter.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,12 @@
2424

2525
import org.springframework.core.log.LogMessage;
2626
import org.springframework.http.HttpMethod;
27-
import org.springframework.http.HttpStatus;
2827
import org.springframework.http.converter.HttpMessageConverter;
2928
import org.springframework.http.server.ServletServerHttpResponse;
3029
import org.springframework.security.authentication.AbstractAuthenticationToken;
3130
import org.springframework.security.authentication.AuthenticationDetailsSource;
3231
import org.springframework.security.authentication.AuthenticationManager;
3332
import org.springframework.security.core.Authentication;
34-
import org.springframework.security.core.AuthenticationException;
3533
import org.springframework.security.core.context.SecurityContextHolder;
3634
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
3735
import org.springframework.security.oauth2.core.OAuth2DeviceCode;
@@ -44,6 +42,7 @@
4442
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceAuthorizationRequestAuthenticationProvider;
4543
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceAuthorizationRequestAuthenticationToken;
4644
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder;
45+
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ErrorAuthenticationFailureHandler;
4746
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2DeviceAuthorizationRequestAuthenticationConverter;
4847
import org.springframework.security.web.authentication.AuthenticationConverter;
4948
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
@@ -76,13 +75,11 @@ public final class OAuth2DeviceAuthorizationEndpointFilter extends OncePerReques
7675
private final RequestMatcher deviceAuthorizationEndpointMatcher;
7776
private final HttpMessageConverter<OAuth2DeviceAuthorizationResponse> deviceAuthorizationHttpResponseConverter =
7877
new OAuth2DeviceAuthorizationResponseHttpMessageConverter();
79-
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
80-
new OAuth2ErrorHttpMessageConverter();
8178
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource =
8279
new WebAuthenticationDetailsSource();
8380
private AuthenticationConverter authenticationConverter;
8481
private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendDeviceAuthorizationResponse;
85-
private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
82+
private AuthenticationFailureHandler authenticationFailureHandler = new OAuth2ErrorAuthenticationFailureHandler();
8683
private String verificationUri = OAuth2DeviceVerificationEndpointFilter.DEFAULT_DEVICE_VERIFICATION_ENDPOINT_URI;
8784

8885
/**
@@ -225,13 +222,4 @@ private void sendDeviceAuthorizationResponse(HttpServletRequest request, HttpSer
225222
this.deviceAuthorizationHttpResponseConverter.write(deviceAuthorizationResponse, null, httpResponse);
226223
}
227224

228-
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
229-
AuthenticationException authenticationException) throws IOException {
230-
231-
OAuth2Error error = ((OAuth2AuthenticationException) authenticationException).getError();
232-
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
233-
httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
234-
this.errorHttpResponseConverter.write(error, null, httpResponse);
235-
}
236-
237225
}

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,12 @@
2727

2828
import org.springframework.core.log.LogMessage;
2929
import org.springframework.http.HttpMethod;
30-
import org.springframework.http.HttpStatus;
3130
import org.springframework.http.converter.HttpMessageConverter;
3231
import org.springframework.http.server.ServletServerHttpResponse;
3332
import org.springframework.security.authentication.AbstractAuthenticationToken;
3433
import org.springframework.security.authentication.AuthenticationDetailsSource;
3534
import org.springframework.security.authentication.AuthenticationManager;
3635
import org.springframework.security.core.Authentication;
37-
import org.springframework.security.core.AuthenticationException;
3836
import org.springframework.security.core.context.SecurityContextHolder;
3937
import org.springframework.security.oauth2.core.OAuth2AccessToken;
4038
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
@@ -51,6 +49,7 @@
5149
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationProvider;
5250
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceCodeAuthenticationProvider;
5351
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationProvider;
52+
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ErrorAuthenticationFailureHandler;
5453
import org.springframework.security.oauth2.server.authorization.web.authentication.DelegatingAuthenticationConverter;
5554
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeAuthenticationConverter;
5655
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ClientCredentialsAuthenticationConverter;
@@ -107,13 +106,11 @@ public final class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
107106
private final RequestMatcher tokenEndpointMatcher;
108107
private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter =
109108
new OAuth2AccessTokenResponseHttpMessageConverter();
110-
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
111-
new OAuth2ErrorHttpMessageConverter();
112109
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource =
113110
new WebAuthenticationDetailsSource();
114111
private AuthenticationConverter authenticationConverter;
115112
private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendAccessTokenResponse;
116-
private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
113+
private AuthenticationFailureHandler authenticationFailureHandler = new OAuth2ErrorAuthenticationFailureHandler();
117114

118115
/**
119116
* Constructs an {@code OAuth2TokenEndpointFilter} using the provided parameters.
@@ -250,15 +247,6 @@ private void sendAccessTokenResponse(HttpServletRequest request, HttpServletResp
250247
this.accessTokenHttpResponseConverter.write(accessTokenResponse, null, httpResponse);
251248
}
252249

253-
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
254-
AuthenticationException exception) throws IOException {
255-
256-
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
257-
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
258-
httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
259-
this.errorHttpResponseConverter.write(error, null, httpResponse);
260-
}
261-
262250
private static void throwError(String errorCode, String parameterName) {
263251
OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, DEFAULT_ERROR_URI);
264252
throw new OAuth2AuthenticationException(error);

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenIntrospectionEndpointFilter.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,12 +24,10 @@
2424

2525
import org.springframework.core.log.LogMessage;
2626
import org.springframework.http.HttpMethod;
27-
import org.springframework.http.HttpStatus;
2827
import org.springframework.http.converter.HttpMessageConverter;
2928
import org.springframework.http.server.ServletServerHttpResponse;
3029
import org.springframework.security.authentication.AuthenticationManager;
3130
import org.springframework.security.core.Authentication;
32-
import org.springframework.security.core.AuthenticationException;
3331
import org.springframework.security.core.context.SecurityContextHolder;
3432
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
3533
import org.springframework.security.oauth2.core.OAuth2Error;
@@ -38,6 +36,7 @@
3836
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenIntrospectionAuthenticationProvider;
3937
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenIntrospectionAuthenticationToken;
4038
import org.springframework.security.oauth2.server.authorization.http.converter.OAuth2TokenIntrospectionHttpMessageConverter;
39+
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ErrorAuthenticationFailureHandler;
4140
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2TokenIntrospectionAuthenticationConverter;
4241
import org.springframework.security.web.authentication.AuthenticationConverter;
4342
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
@@ -69,9 +68,8 @@ public final class OAuth2TokenIntrospectionEndpointFilter extends OncePerRequest
6968
private AuthenticationConverter authenticationConverter;
7069
private final HttpMessageConverter<OAuth2TokenIntrospection> tokenIntrospectionHttpResponseConverter =
7170
new OAuth2TokenIntrospectionHttpMessageConverter();
72-
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter = new OAuth2ErrorHttpMessageConverter();
7371
private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendIntrospectionResponse;
74-
private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
72+
private AuthenticationFailureHandler authenticationFailureHandler = new OAuth2ErrorAuthenticationFailureHandler();
7573

7674
/**
7775
* Constructs an {@code OAuth2TokenIntrospectionEndpointFilter} using the provided parameters.
@@ -166,12 +164,4 @@ private void sendIntrospectionResponse(HttpServletRequest request, HttpServletRe
166164
this.tokenIntrospectionHttpResponseConverter.write(tokenClaims, null, httpResponse);
167165
}
168166

169-
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
170-
AuthenticationException exception) throws IOException {
171-
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
172-
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
173-
httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
174-
this.errorHttpResponseConverter.write(error, null, httpResponse);
175-
}
176-
177167
}

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenRevocationEndpointFilter.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,17 +25,15 @@
2525
import org.springframework.core.log.LogMessage;
2626
import org.springframework.http.HttpMethod;
2727
import org.springframework.http.HttpStatus;
28-
import org.springframework.http.converter.HttpMessageConverter;
29-
import org.springframework.http.server.ServletServerHttpResponse;
3028
import org.springframework.security.authentication.AuthenticationManager;
3129
import org.springframework.security.core.Authentication;
32-
import org.springframework.security.core.AuthenticationException;
3330
import org.springframework.security.core.context.SecurityContextHolder;
3431
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
3532
import org.springframework.security.oauth2.core.OAuth2Error;
3633
import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter;
3734
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationProvider;
3835
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationToken;
36+
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ErrorAuthenticationFailureHandler;
3937
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2TokenRevocationAuthenticationConverter;
4038
import org.springframework.security.web.authentication.AuthenticationConverter;
4139
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
@@ -65,10 +63,8 @@ public final class OAuth2TokenRevocationEndpointFilter extends OncePerRequestFil
6563
private final AuthenticationManager authenticationManager;
6664
private final RequestMatcher tokenRevocationEndpointMatcher;
6765
private AuthenticationConverter authenticationConverter;
68-
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
69-
new OAuth2ErrorHttpMessageConverter();
7066
private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendRevocationSuccessResponse;
71-
private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
67+
private AuthenticationFailureHandler authenticationFailureHandler = new OAuth2ErrorAuthenticationFailureHandler();
7268

7369
/**
7470
* Constructs an {@code OAuth2TokenRevocationEndpointFilter} using the provided parameters.
@@ -157,12 +153,4 @@ private void sendRevocationSuccessResponse(HttpServletRequest request, HttpServl
157153
response.setStatus(HttpStatus.OK.value());
158154
}
159155

160-
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
161-
AuthenticationException exception) throws IOException {
162-
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
163-
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
164-
httpResponse.setStatusCode(HttpStatus.BAD_REQUEST);
165-
this.errorHttpResponseConverter.write(error, null, httpResponse);
166-
}
167-
168156
}

0 commit comments

Comments
 (0)