Polish OAuth2ClientAuthenticationFilter

This commit is contained in:
Joe Grandja
2021-07-29 05:39:30 -04:00
parent 7f294abfbb
commit 850bd76aee

View File

@@ -59,8 +59,8 @@ import org.springframework.web.filter.OncePerRequestFilter;
* @since 0.0.1
* @see AuthenticationManager
* @see OAuth2ClientAuthenticationProvider
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-2.3">Section 2.3 Client Authentication</a>
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-3.2.1">Section 3.2.1 Token Endpoint Client Authentication</a>
* @see <a target="_blank" href="https://datatracker.ietf.org/doc/html/rfc6749#section-2.3">Section 2.3 Client Authentication</a>
* @see <a target="_blank" href="https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1">Section 3.2.1 Token Endpoint Client Authentication</a>
*/
public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter {
private final AuthenticationManager authenticationManager;
@@ -69,8 +69,8 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
private final AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource =
new WebAuthenticationDetailsSource();
private AuthenticationConverter authenticationConverter;
private AuthenticationSuccessHandler authenticationSuccessHandler;
private AuthenticationFailureHandler authenticationFailureHandler;
private AuthenticationSuccessHandler authenticationSuccessHandler = this::onAuthenticationSuccess;
private AuthenticationFailureHandler authenticationFailureHandler = this::onAuthenticationFailure;
/**
* Constructs an {@code OAuth2ClientAuthenticationFilter} using the provided parameters.
@@ -89,37 +89,39 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
new ClientSecretBasicAuthenticationConverter(),
new ClientSecretPostAuthenticationConverter(),
new PublicClientAuthenticationConverter()));
this.authenticationSuccessHandler = this::onAuthenticationSuccess;
this.authenticationFailureHandler = this::onAuthenticationFailure;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (this.requestMatcher.matches(request)) {
try {
Authentication authenticationRequest = this.authenticationConverter.convert(request);
if (authenticationRequest instanceof AbstractAuthenticationToken) {
((AbstractAuthenticationToken) authenticationRequest).setDetails(
this.authenticationDetailsSource.buildDetails(request));
}
if (authenticationRequest != null) {
Authentication authenticationResult = this.authenticationManager.authenticate(authenticationRequest);
this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authenticationResult);
}
} catch (OAuth2AuthenticationException failed) {
this.authenticationFailureHandler.onAuthenticationFailure(request, response, failed);
return;
}
if (!this.requestMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
try {
Authentication authenticationRequest = this.authenticationConverter.convert(request);
if (authenticationRequest instanceof AbstractAuthenticationToken) {
((AbstractAuthenticationToken) authenticationRequest).setDetails(
this.authenticationDetailsSource.buildDetails(request));
}
if (authenticationRequest != null) {
Authentication authenticationResult = this.authenticationManager.authenticate(authenticationRequest);
this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authenticationResult);
}
filterChain.doFilter(request, response);
} catch (OAuth2AuthenticationException ex) {
this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex);
}
filterChain.doFilter(request, response);
}
/**
* Sets the {@link AuthenticationConverter} used for converting a {@link HttpServletRequest} to an {@link OAuth2ClientAuthenticationToken}.
* Sets the {@link AuthenticationConverter} used when attempting to extract client credentials from {@link HttpServletRequest}
* to an instance of {@link OAuth2ClientAuthenticationToken} used for authenticating the client.
*
* @param authenticationConverter used for converting a {@link HttpServletRequest} to an {@link OAuth2ClientAuthenticationToken}
* @param authenticationConverter the {@link AuthenticationConverter} used when attempting to extract client credentials from {@link HttpServletRequest}
*/
public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
@@ -127,9 +129,10 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
}
/**
* Sets the {@link AuthenticationSuccessHandler} used for handling successful authentications.
* Sets the {@link AuthenticationSuccessHandler} used for handling a successful client authentication
* and associating the {@link OAuth2ClientAuthenticationToken} to the {@link SecurityContext}.
*
* @param authenticationSuccessHandler the {@link AuthenticationSuccessHandler} used for handling successful authentications
* @param authenticationSuccessHandler the {@link AuthenticationSuccessHandler} used for handling a successful client authentication
*/
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler authenticationSuccessHandler) {
Assert.notNull(authenticationSuccessHandler, "authenticationSuccessHandler cannot be null");
@@ -137,9 +140,10 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
}
/**
* Sets the {@link AuthenticationFailureHandler} used for handling failed authentications.
* Sets the {@link AuthenticationFailureHandler} used for handling a failed client authentication
* and returning the {@link OAuth2Error Error Response}.
*
* @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used for handling failed authentications
* @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used for handling a failed client authentication
*/
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
Assert.notNull(authenticationFailureHandler, "authenticationFailureHandler cannot be null");
@@ -149,13 +153,13 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
private void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authentication);
SecurityContextHolder.setContext(securityContext);
}
private void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException {
AuthenticationException exception) throws IOException {
SecurityContextHolder.clearContext();
@@ -167,7 +171,7 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
// include the "WWW-Authenticate" response header field
// matching the authentication scheme used by the client.
OAuth2Error error = ((OAuth2AuthenticationException) failed).getError();
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
if (OAuth2ErrorCodes.INVALID_CLIENT.equals(error.getErrorCode())) {
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
@@ -176,4 +180,5 @@ public final class OAuth2ClientAuthenticationFilter extends OncePerRequestFilter
}
this.errorHttpResponseConverter.write(error, null, httpResponse);
}
}