From 2c4bd29f989ecde657ad404fdafe3bb423f16d39 Mon Sep 17 00:00:00 2001 From: Steve Riesenberg Date: Thu, 3 Nov 2022 14:27:33 -0500 Subject: [PATCH] Add logging for authentication providers Issue gh-159 --- .../ClientSecretAuthenticationProvider.java | 16 +++++++ .../CodeVerifierAuthenticator.java | 19 ++++++++ ...ClientAssertionAuthenticationProvider.java | 16 +++++++ ...thorizationCodeAuthenticationProvider.java | 44 +++++++++++++++++++ ...tionCodeRequestAuthenticationProvider.java | 36 +++++++++++++++ ...rizationConsentAuthenticationProvider.java | 43 ++++++++++++++++++ ...ientCredentialsAuthenticationProvider.java | 23 ++++++++++ ...th2RefreshTokenAuthenticationProvider.java | 40 +++++++++++++++++ ...enIntrospectionAuthenticationProvider.java | 18 ++++++++ ...TokenRevocationAuthenticationProvider.java | 13 ++++++ .../PublicClientAuthenticationProvider.java | 16 +++++++ ...ntConfigurationAuthenticationProvider.java | 16 +++++++ ...entRegistrationAuthenticationProvider.java | 33 ++++++++++++++ .../OidcUserInfoAuthenticationProvider.java | 16 +++++++ 14 files changed, 349 insertions(+) diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProvider.java index 974952dc..60e82485 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProvider.java @@ -17,6 +17,9 @@ package org.springframework.security.oauth2.server.authorization.authentication; import java.time.Instant; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -47,6 +50,7 @@ import org.springframework.util.Assert; */ public final class ClientSecretAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1"; + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final CodeVerifierAuthenticator codeVerifierAuthenticator; private PasswordEncoder passwordEncoder; @@ -95,6 +99,10 @@ public final class ClientSecretAuthenticationProvider implements AuthenticationP throwInvalidClient(OAuth2ParameterNames.CLIENT_ID); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + if (!registeredClient.getClientAuthenticationMethods().contains( clientAuthentication.getClientAuthenticationMethod())) { throwInvalidClient("authentication_method"); @@ -114,9 +122,17 @@ public final class ClientSecretAuthenticationProvider implements AuthenticationP throwInvalidClient("client_secret_expires_at"); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated client authentication parameters"); + } + // Validate the "code_verifier" parameter for the confidential client, if available this.codeVerifierAuthenticator.authenticateIfAvailable(clientAuthentication, registeredClient); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated client secret"); + } + return new OAuth2ClientAuthenticationToken(registeredClient, clientAuthentication.getClientAuthenticationMethod(), clientAuthentication.getCredentials()); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java index 588b7e71..98a577ee 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java @@ -21,6 +21,9 @@ import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; @@ -47,6 +50,7 @@ import org.springframework.util.StringUtils; */ final class CodeVerifierAuthenticator { private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE); + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; CodeVerifierAuthenticator(OAuth2AuthorizationService authorizationService) { @@ -81,6 +85,10 @@ final class CodeVerifierAuthenticator { throwInvalidGrant(OAuth2ParameterNames.CODE); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with authorization code"); + } + OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute( OAuth2AuthorizationRequest.class.getName()); @@ -90,10 +98,17 @@ final class CodeVerifierAuthenticator { if (registeredClient.getClientSettings().isRequireProofKey()) { throwInvalidGrant(PkceParameterNames.CODE_CHALLENGE); } else { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Did not authenticate code verifier since requireProofKey=false"); + } return false; } } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated code verifier parameters"); + } + String codeChallengeMethod = (String) authorizationRequest.getAdditionalParameters() .get(PkceParameterNames.CODE_CHALLENGE_METHOD); String codeVerifier = (String) parameters.get(PkceParameterNames.CODE_VERIFIER); @@ -101,6 +116,10 @@ final class CodeVerifierAuthenticator { throwInvalidGrant(PkceParameterNames.CODE_VERIFIER); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated code verifier"); + } + return true; } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/JwtClientAssertionAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/JwtClientAssertionAuthenticationProvider.java index 5a05a426..2adc8c98 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/JwtClientAssertionAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/JwtClientAssertionAuthenticationProvider.java @@ -15,6 +15,9 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -50,6 +53,7 @@ public final class JwtClientAssertionAuthenticationProvider implements Authentic private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1"; private static final ClientAuthenticationMethod JWT_CLIENT_ASSERTION_AUTHENTICATION_METHOD = new ClientAuthenticationMethod("urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final CodeVerifierAuthenticator codeVerifierAuthenticator; private JwtDecoderFactory jwtDecoderFactory; @@ -84,6 +88,10 @@ public final class JwtClientAssertionAuthenticationProvider implements Authentic throwInvalidClient(OAuth2ParameterNames.CLIENT_ID); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + if (!registeredClient.getClientAuthenticationMethods().contains(ClientAuthenticationMethod.PRIVATE_KEY_JWT) && !registeredClient.getClientAuthenticationMethods().contains(ClientAuthenticationMethod.CLIENT_SECRET_JWT)) { throwInvalidClient("authentication_method"); @@ -101,6 +109,10 @@ public final class JwtClientAssertionAuthenticationProvider implements Authentic throwInvalidClient(OAuth2ParameterNames.CLIENT_ASSERTION, ex); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated client authentication parameters"); + } + // Validate the "code_verifier" parameter for the confidential client, if available this.codeVerifierAuthenticator.authenticateIfAvailable(clientAuthentication, registeredClient); @@ -109,6 +121,10 @@ public final class JwtClientAssertionAuthenticationProvider implements Authentic ClientAuthenticationMethod.PRIVATE_KEY_JWT : ClientAuthenticationMethod.CLIENT_SECRET_JWT; + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated client assertion"); + } + return new OAuth2ClientAuthenticationToken(registeredClient, clientAuthenticationMethod, jwtAssertion); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java index 4550dc7e..b795674c 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProvider.java @@ -20,6 +20,10 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.log.LogMessage; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -72,6 +76,7 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth new OAuth2TokenType(OAuth2ParameterNames.CODE); private static final OAuth2TokenType ID_TOKEN_TOKEN_TYPE = new OAuth2TokenType(OidcParameterNames.ID_TOKEN); + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator tokenGenerator; @@ -99,11 +104,20 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth getAuthenticatedClientElseThrowInvalidClient(authorizationCodeAuthentication); RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + OAuth2Authorization authorization = this.authorizationService.findByToken( authorizationCodeAuthentication.getCode(), AUTHORIZATION_CODE_TOKEN_TYPE); if (authorization == null) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_GRANT); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with authorization code"); + } + OAuth2Authorization.Token authorizationCode = authorization.getToken(OAuth2AuthorizationCode.class); @@ -115,6 +129,9 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth // Invalidate the authorization code given that a different client is attempting to use it authorization = OAuth2AuthenticationProviderUtils.invalidate(authorization, authorizationCode.getToken()); this.authorizationService.save(authorization); + if (this.logger.isWarnEnabled()) { + this.logger.warn(LogMessage.format("Invalidated authorization code used by registered client '%s'", registeredClient.getId())); + } } throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_GRANT); } @@ -128,6 +145,10 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_GRANT); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated token request parameters"); + } + // @formatter:off DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() .registeredClient(registeredClient) @@ -149,6 +170,11 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth "The token generator failed to generate the access token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated access token"); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); @@ -172,6 +198,11 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth "The token generator failed to generate the refresh token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated refresh token"); + } + refreshToken = (OAuth2RefreshToken) generatedRefreshToken; authorizationBuilder.refreshToken(refreshToken); } @@ -191,6 +222,11 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth "The token generator failed to generate the ID token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated id token"); + } + idToken = new OidcIdToken(generatedIdToken.getTokenValue(), generatedIdToken.getIssuedAt(), generatedIdToken.getExpiresAt(), ((Jwt) generatedIdToken).getClaims()); authorizationBuilder.token(idToken, (metadata) -> @@ -206,12 +242,20 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + } + Map additionalParameters = Collections.emptyMap(); if (idToken != null) { additionalParameters = new HashMap<>(); additionalParameters.put(OidcParameterNames.ID_TOKEN, idToken.getTokenValue()); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated token request"); + } + return new OAuth2AccessTokenAuthenticationToken( registeredClient, clientPrincipal, accessToken, refreshToken, additionalParameters); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java index 3fe93cb4..1c3a1666 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java @@ -20,6 +20,9 @@ import java.util.Base64; import java.util.Set; import java.util.function.Consumer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; @@ -69,6 +72,7 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen private static final String PKCE_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc7636#section-4.4.1"; private static final StringKeyGenerator DEFAULT_STATE_GENERATOR = new Base64StringKeyGenerator(Base64.getUrlEncoder()); + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; private final OAuth2AuthorizationConsentService authorizationConsentService; @@ -105,6 +109,10 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen authorizationCodeRequestAuthentication, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext = OAuth2AuthorizationCodeRequestAuthenticationContext.with(authorizationCodeRequestAuthentication) .registeredClient(registeredClient) @@ -129,12 +137,19 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen authorizationCodeRequestAuthentication, registeredClient, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated authorization code request parameters"); + } + // --------------- // The request is valid - ensure the resource owner is authenticated // --------------- Authentication principal = (Authentication) authorizationCodeRequestAuthentication.getPrincipal(); if (!isPrincipalAuthenticated(principal)) { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Did not authenticate authorization code request since principal not authenticated"); + } // Return the authorization request as-is where isAuthenticated() is false return authorizationCodeRequestAuthentication; } @@ -156,11 +171,20 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest) .attribute(OAuth2ParameterNames.STATE, state) .build(); + + if (this.logger.isTraceEnabled()) { + logger.trace("Generated authorization consent state"); + } + this.authorizationService.save(authorization); Set currentAuthorizedScopes = currentAuthorizationConsent != null ? currentAuthorizationConsent.getScopes() : null; + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + } + return new OAuth2AuthorizationConsentAuthenticationToken(authorizationRequest.getAuthorizationUri(), registeredClient.getClientId(), principal, state, currentAuthorizedScopes, null); } @@ -174,17 +198,29 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated authorization code"); + } + OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest) .authorizedScopes(authorizationRequest.getScopes()) .token(authorizationCode) .build(); this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + } + String redirectUri = authorizationRequest.getRedirectUri(); if (!StringUtils.hasText(redirectUri)) { redirectUri = registeredClient.getRedirectUris().iterator().next(); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated authorization code request"); + } + return new OAuth2AuthorizationCodeRequestAuthenticationToken(authorizationRequest.getAuthorizationUri(), registeredClient.getClientId(), principal, authorizationCode, redirectUri, authorizationRequest.getState(), authorizationRequest.getScopes()); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationConsentAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationConsentAuthenticationProvider.java index 46199dfa..9603393d 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationConsentAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationConsentAuthenticationProvider.java @@ -20,6 +20,9 @@ import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; @@ -62,6 +65,7 @@ import org.springframework.util.StringUtils; public final class OAuth2AuthorizationConsentAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1"; private static final OAuth2TokenType STATE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.STATE); + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; private final OAuth2AuthorizationConsentService authorizationConsentService; @@ -97,6 +101,10 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A authorizationConsentAuthentication, null, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with authorization consent state"); + } + // The 'in-flight' authorization must be associated to the current principal Authentication principal = (Authentication) authorizationConsentAuthentication.getPrincipal(); if (!isPrincipalAuthenticated(principal) || !principal.getName().equals(authorization.getPrincipalName())) { @@ -111,6 +119,10 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A authorizationConsentAuthentication, registeredClient, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + OAuth2AuthorizationRequest authorizationRequest = authorization.getAttribute(OAuth2AuthorizationRequest.class.getName()); Set requestedScopes = authorizationRequest.getScopes(); Set authorizedScopes = new HashSet<>(authorizationConsentAuthentication.getScopes()); @@ -119,6 +131,10 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A authorizationConsentAuthentication, registeredClient, authorizationRequest); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated authorization consent request parameters"); + } + OAuth2AuthorizationConsent currentAuthorizationConsent = this.authorizationConsentService.findById( authorization.getRegisteredClientId(), authorization.getPrincipalName()); Set currentAuthorizedScopes = currentAuthorizationConsent != null ? @@ -139,6 +155,9 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A OAuth2AuthorizationConsent.Builder authorizationConsentBuilder; if (currentAuthorizationConsent != null) { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved existing authorization consent"); + } authorizationConsentBuilder = OAuth2AuthorizationConsent.from(currentAuthorizationConsent); } else { authorizationConsentBuilder = OAuth2AuthorizationConsent.withId( @@ -157,6 +176,9 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A .build(); // @formatter:on this.authorizationConsentCustomizer.accept(authorizationConsentAuthenticationContext); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Customized authorization consent"); + } } Set authorities = new HashSet<>(); @@ -166,8 +188,14 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A // Authorization consent denied (or revoked) if (currentAuthorizationConsent != null) { this.authorizationConsentService.remove(currentAuthorizationConsent); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Revoked authorization consent"); + } } this.authorizationService.remove(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Removed authorization"); + } throwError(OAuth2ErrorCodes.ACCESS_DENIED, OAuth2ParameterNames.CLIENT_ID, authorizationConsentAuthentication, registeredClient, authorizationRequest); } @@ -175,6 +203,9 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A OAuth2AuthorizationConsent authorizationConsent = authorizationConsentBuilder.build(); if (!authorizationConsent.equals(currentAuthorizationConsent)) { this.authorizationConsentService.save(authorizationConsent); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization consent"); + } } OAuth2TokenContext tokenContext = createAuthorizationCodeTokenContext( @@ -186,6 +217,10 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated authorization code"); + } + OAuth2Authorization updatedAuthorization = OAuth2Authorization.from(authorization) .authorizedScopes(authorizedScopes) .token(authorizationCode) @@ -195,11 +230,19 @@ public final class OAuth2AuthorizationConsentAuthenticationProvider implements A .build(); this.authorizationService.save(updatedAuthorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + } + String redirectUri = authorizationRequest.getRedirectUri(); if (!StringUtils.hasText(redirectUri)) { redirectUri = registeredClient.getRedirectUris().iterator().next(); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated authorization consent request"); + } + return new OAuth2AuthorizationCodeRequestAuthenticationToken( authorizationRequest.getAuthorizationUri(), registeredClient.getClientId(), principal, authorizationCode, redirectUri, authorizationRequest.getState(), authorizedScopes); diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java index 0e4b7298..dc0fcff1 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java @@ -19,6 +19,9 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -57,6 +60,7 @@ import static org.springframework.security.oauth2.server.authorization.authentic */ public final class OAuth2ClientCredentialsAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator tokenGenerator; @@ -84,6 +88,10 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth getAuthenticatedClientElseThrowInvalidClient(clientCredentialsAuthentication); RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + if (!registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.CLIENT_CREDENTIALS)) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT); } @@ -98,6 +106,10 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth authorizedScopes = new LinkedHashSet<>(clientCredentialsAuthentication.getScopes()); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated token request parameters"); + } + // @formatter:off OAuth2TokenContext tokenContext = DefaultOAuth2TokenContext.builder() .registeredClient(registeredClient) @@ -116,6 +128,11 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth "The token generator failed to generate the access token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated access token"); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); @@ -137,6 +154,12 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + // This log is kept separate for consistency with other providers + this.logger.trace("Authenticated token request"); + } + return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java index ccdf5485..83cc9881 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProvider.java @@ -21,6 +21,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -65,6 +68,7 @@ import static org.springframework.security.oauth2.server.authorization.authentic public final class OAuth2RefreshTokenAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; private static final OAuth2TokenType ID_TOKEN_TOKEN_TYPE = new OAuth2TokenType(OidcParameterNames.ID_TOKEN); + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator tokenGenerator; @@ -92,12 +96,20 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic getAuthenticatedClientElseThrowInvalidClient(refreshTokenAuthentication); RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + OAuth2Authorization authorization = this.authorizationService.findByToken( refreshTokenAuthentication.getRefreshToken(), OAuth2TokenType.REFRESH_TOKEN); if (authorization == null) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_GRANT); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with refresh token"); + } + if (!registeredClient.getId().equals(authorization.getRegisteredClientId())) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); } @@ -122,6 +134,11 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic if (!authorizedScopes.containsAll(scopes)) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_SCOPE); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated token request parameters"); + } + if (scopes.isEmpty()) { scopes = authorizedScopes; } @@ -147,6 +164,11 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic "The token generator failed to generate the access token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated access token"); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); @@ -169,6 +191,11 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic "The token generator failed to generate the refresh token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated refresh token"); + } + currentRefreshToken = (OAuth2RefreshToken) generatedRefreshToken; authorizationBuilder.refreshToken(currentRefreshToken); } @@ -188,6 +215,11 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic "The token generator failed to generate the ID token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated id token"); + } + idToken = new OidcIdToken(generatedIdToken.getTokenValue(), generatedIdToken.getIssuedAt(), generatedIdToken.getExpiresAt(), ((Jwt) generatedIdToken).getClaims()); authorizationBuilder.token(idToken, (metadata) -> @@ -200,12 +232,20 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization"); + } + Map additionalParameters = Collections.emptyMap(); if (idToken != null) { additionalParameters = new HashMap<>(); additionalParameters.put(OidcParameterNames.ID_TOKEN, idToken.getTokenValue()); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated token request"); + } + return new OAuth2AccessTokenAuthenticationToken( registeredClient, clientPrincipal, accessToken, currentRefreshToken, additionalParameters); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenIntrospectionAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenIntrospectionAuthenticationProvider.java index 58d5d5d3..d1a4f80b 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenIntrospectionAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenIntrospectionAuthenticationProvider.java @@ -20,6 +20,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.core.convert.TypeDescriptor; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; @@ -53,6 +56,7 @@ public final class OAuth2TokenIntrospectionAuthenticationProvider implements Aut private static final TypeDescriptor OBJECT_TYPE_DESCRIPTOR = TypeDescriptor.valueOf(Object.class); private static final TypeDescriptor LIST_STRING_TYPE_DESCRIPTOR = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class)); + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; @@ -81,13 +85,23 @@ public final class OAuth2TokenIntrospectionAuthenticationProvider implements Aut OAuth2Authorization authorization = this.authorizationService.findByToken( tokenIntrospectionAuthentication.getToken(), null); if (authorization == null) { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Did not authenticate token introspection request since token was not found"); + } // Return the authentication request when token not found return tokenIntrospectionAuthentication; } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with token"); + } + OAuth2Authorization.Token authorizedToken = authorization.getToken(tokenIntrospectionAuthentication.getToken()); if (!authorizedToken.isActive()) { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Did not introspect token since not active"); + } return new OAuth2TokenIntrospectionAuthenticationToken(tokenIntrospectionAuthentication.getToken(), clientPrincipal, OAuth2TokenIntrospection.builder().build()); } @@ -95,6 +109,10 @@ public final class OAuth2TokenIntrospectionAuthenticationProvider implements Aut RegisteredClient authorizedClient = this.registeredClientRepository.findById(authorization.getRegisteredClientId()); OAuth2TokenIntrospection tokenClaims = withActiveTokenClaims(authorizedToken, authorizedClient); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated token introspection request"); + } + return new OAuth2TokenIntrospectionAuthenticationToken(authorizedToken.getToken().getTokenValue(), clientPrincipal, tokenClaims); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenRevocationAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenRevocationAuthenticationProvider.java index 377e7e5e..4e18aa7c 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenRevocationAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2TokenRevocationAuthenticationProvider.java @@ -15,6 +15,9 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -39,6 +42,7 @@ import static org.springframework.security.oauth2.server.authorization.authentic * @see Section 2.1 Revocation Request */ public final class OAuth2TokenRevocationAuthenticationProvider implements AuthenticationProvider { + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; /** @@ -63,6 +67,9 @@ public final class OAuth2TokenRevocationAuthenticationProvider implements Authen OAuth2Authorization authorization = this.authorizationService.findByToken( tokenRevocationAuthentication.getToken(), null); if (authorization == null) { + if (this.logger.isTraceEnabled()) { + this.logger.trace("Did not authenticate token revocation request since token was not found"); + } // Return the authentication request when token not found return tokenRevocationAuthentication; } @@ -75,6 +82,12 @@ public final class OAuth2TokenRevocationAuthenticationProvider implements Authen authorization = OAuth2AuthenticationProviderUtils.invalidate(authorization, token.getToken()); this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization with revoked token"); + // This log is kept separate for consistency with other providers + this.logger.trace("Authenticated token revocation request"); + } + return new OAuth2TokenRevocationAuthenticationToken(token.getToken(), clientPrincipal); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/PublicClientAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/PublicClientAuthenticationProvider.java index 2d7c7669..6e624302 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/PublicClientAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/PublicClientAuthenticationProvider.java @@ -15,6 +15,9 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -42,6 +45,7 @@ import org.springframework.util.Assert; */ public final class PublicClientAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1"; + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final CodeVerifierAuthenticator codeVerifierAuthenticator; @@ -74,14 +78,26 @@ public final class PublicClientAuthenticationProvider implements AuthenticationP throwInvalidClient(OAuth2ParameterNames.CLIENT_ID); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved registered client"); + } + if (!registeredClient.getClientAuthenticationMethods().contains( clientAuthentication.getClientAuthenticationMethod())) { throwInvalidClient("authentication_method"); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated client authentication parameters"); + } + // Validate the "code_verifier" parameter for the public client this.codeVerifierAuthenticator.authenticateRequired(clientAuthentication, registeredClient); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated public client"); + } + return new OAuth2ClientAuthenticationToken(registeredClient, clientAuthentication.getClientAuthenticationMethod(), null); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientConfigurationAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientConfigurationAuthenticationProvider.java index 5ce732b7..c33c76fd 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientConfigurationAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientConfigurationAuthenticationProvider.java @@ -19,6 +19,9 @@ import java.util.Collection; import java.util.Collections; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.core.convert.converter.Converter; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; @@ -52,6 +55,7 @@ import org.springframework.util.StringUtils; */ public final class OidcClientConfigurationAuthenticationProvider implements AuthenticationProvider { static final String DEFAULT_CLIENT_CONFIGURATION_AUTHORIZED_SCOPE = "client.read"; + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; private final Converter clientRegistrationConverter; @@ -98,6 +102,10 @@ public final class OidcClientConfigurationAuthenticationProvider implements Auth throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with access token"); + } + OAuth2Authorization.Token authorizedAccessToken = authorization.getAccessToken(); if (!authorizedAccessToken.isActive()) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); @@ -125,8 +133,16 @@ public final class OidcClientConfigurationAuthenticationProvider implements Auth throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated client configuration request parameters"); + } + OidcClientRegistration clientRegistration = this.clientRegistrationConverter.convert(registeredClient); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated client configuration request"); + } + return new OidcClientRegistrationAuthenticationToken( (Authentication) clientRegistrationAuthentication.getPrincipal(), clientRegistration); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java index 81e88c79..97166d0d 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java @@ -27,6 +27,9 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.core.convert.converter.Converter; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; @@ -81,6 +84,7 @@ import org.springframework.util.StringUtils; public final class OidcClientRegistrationAuthenticationProvider implements AuthenticationProvider { private static final String ERROR_URI = "https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError"; private static final String DEFAULT_CLIENT_REGISTRATION_AUTHORIZED_SCOPE = "client.create"; + private final Log logger = LogFactory.getLog(getClass()); private final RegisteredClientRepository registeredClientRepository; private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator tokenGenerator; @@ -134,6 +138,10 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with initial access token"); + } + OAuth2Authorization.Token authorizedAccessToken = authorization.getAccessToken(); if (!authorizedAccessToken.isActive()) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); @@ -170,9 +178,17 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe throwInvalidClientRegistration("invalid_client_metadata", OidcClientMetadataClaimNames.TOKEN_ENDPOINT_AUTH_METHOD); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated client registration request parameters"); + } + RegisteredClient registeredClient = this.registeredClientConverter.convert(clientRegistrationAuthentication.getClientRegistration()); this.registeredClientRepository.save(registeredClient); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved registered client"); + } + OAuth2Authorization registeredClientAuthorization = registerAccessToken(registeredClient); // Invalidate the "initial" access token as it can only be used once @@ -182,11 +198,19 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe } this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization with invalidated initial access token"); + } + Map clientRegistrationClaims = this.clientRegistrationConverter.convert(registeredClient).getClaims(); OidcClientRegistration clientRegistration = OidcClientRegistration.withClaims(clientRegistrationClaims) .registrationAccessToken(registeredClientAuthorization.getAccessToken().getToken().getTokenValue()) .build(); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated client registration request"); + } + return new OidcClientRegistrationAuthenticationToken( (Authentication) clientRegistrationAuthentication.getPrincipal(), clientRegistration); } @@ -216,6 +240,11 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe "The token generator failed to generate the registration access token.", ERROR_URI); throw new OAuth2AuthenticationException(error); } + + if (this.logger.isTraceEnabled()) { + this.logger.trace("Generated registration access token"); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, registrationAccessToken.getTokenValue(), registrationAccessToken.getIssuedAt(), registrationAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); @@ -237,6 +266,10 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe this.authorizationService.save(authorization); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Saved authorization with registration access token"); + } + return authorization; } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcUserInfoAuthenticationProvider.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcUserInfoAuthenticationProvider.java index 85824fff..1e64ec40 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcUserInfoAuthenticationProvider.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcUserInfoAuthenticationProvider.java @@ -23,6 +23,9 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -48,6 +51,7 @@ import org.springframework.util.Assert; * @see 5.3. UserInfo Endpoint */ public final class OidcUserInfoAuthenticationProvider implements AuthenticationProvider { + private final Log logger = LogFactory.getLog(getClass()); private final OAuth2AuthorizationService authorizationService; private Function userInfoMapper = new DefaultOidcUserInfoMapper(); @@ -82,6 +86,10 @@ public final class OidcUserInfoAuthenticationProvider implements AuthenticationP throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Retrieved authorization with access token"); + } + OAuth2Authorization.Token authorizedAccessToken = authorization.getAccessToken(); if (!authorizedAccessToken.isActive()) { throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); @@ -96,6 +104,10 @@ public final class OidcUserInfoAuthenticationProvider implements AuthenticationP throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN); } + if (this.logger.isTraceEnabled()) { + this.logger.trace("Validated user info request"); + } + OidcUserInfoAuthenticationContext authenticationContext = OidcUserInfoAuthenticationContext.with(userInfoAuthentication) .accessToken(authorizedAccessToken.getToken()) @@ -103,6 +115,10 @@ public final class OidcUserInfoAuthenticationProvider implements AuthenticationP .build(); OidcUserInfo userInfo = this.userInfoMapper.apply(authenticationContext); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Authenticated user info request"); + } + return new OidcUserInfoAuthenticationToken(accessTokenAuthentication, userInfo); }