diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContext.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContext.java index cb3102da..a9fc77ad 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContext.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContext.java @@ -15,25 +15,26 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; -import org.springframework.lang.Nullable; -import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; -import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AccessTokenResponseAuthenticationSuccessHandler; -import org.springframework.util.Assert; - import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import org.springframework.lang.Nullable; +import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; +import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AccessTokenResponseAuthenticationSuccessHandler; +import org.springframework.util.Assert; + /** - * An {@link OAuth2AuthenticationContext} that holds an {@link OAuth2AccessTokenResponse.Builder} - * and is used when customizing the building of the {@link OAuth2AccessTokenResponse}. + * An {@link OAuth2AuthenticationContext} that holds an {@link OAuth2AccessTokenAuthenticationToken} and additional information + * and is used when customizing the {@link OAuth2AccessTokenResponse}. * * @author Dmitriy Dubson + * @since 1.3 * @see OAuth2AuthenticationContext + * @see OAuth2AccessTokenAuthenticationToken * @see OAuth2AccessTokenResponse * @see OAuth2AccessTokenResponseAuthenticationSuccessHandler#setAccessTokenResponseCustomizer(Consumer) - * @since 1.3 */ public final class OAuth2AccessTokenAuthenticationContext implements OAuth2AuthenticationContext { private final Map context; @@ -56,7 +57,8 @@ public final class OAuth2AccessTokenAuthenticationContext implements OAuth2Authe } /** - * Returns the {@link OAuth2AccessTokenResponse.Builder} access token response builder + * Returns the {@link OAuth2AccessTokenResponse.Builder access token response builder}. + * * @return the {@link OAuth2AccessTokenResponse.Builder} */ public OAuth2AccessTokenResponse.Builder getAccessTokenResponse() { @@ -69,20 +71,22 @@ public final class OAuth2AccessTokenAuthenticationContext implements OAuth2Authe * @param authentication the {@link OAuth2AccessTokenAuthenticationToken} * @return the {@link Builder} */ - public static OAuth2AccessTokenAuthenticationContext.Builder with(OAuth2AccessTokenAuthenticationToken authentication) { - return new OAuth2AccessTokenAuthenticationContext.Builder(authentication); + public static Builder with(OAuth2AccessTokenAuthenticationToken authentication) { + return new Builder(authentication); } /** - * A builder for {@link OAuth2AccessTokenAuthenticationContext} + * A builder for {@link OAuth2AccessTokenAuthenticationContext}. */ public static final class Builder extends AbstractBuilder { + private Builder(OAuth2AccessTokenAuthenticationToken authentication) { super(authentication); } /** - * Sets the {@link OAuth2AccessTokenResponse.Builder} access token response builder + * Sets the {@link OAuth2AccessTokenResponse.Builder access token response builder}. + * * @param accessTokenResponse the {@link OAuth2AccessTokenResponse.Builder} * @return the {@link Builder} for further configuration */ @@ -97,8 +101,9 @@ public final class OAuth2AccessTokenAuthenticationContext implements OAuth2Authe */ public OAuth2AccessTokenAuthenticationContext build() { Assert.notNull(get(OAuth2AccessTokenResponse.Builder.class), "accessTokenResponse cannot be null"); - return new OAuth2AccessTokenAuthenticationContext(getContext()); } + } + } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java index 5f37cac9..426071f5 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java @@ -22,6 +22,7 @@ import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import org.springframework.core.log.LogMessage; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AbstractAuthenticationToken; @@ -41,12 +42,12 @@ import org.springframework.security.oauth2.server.authorization.authentication.O import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceCodeAuthenticationProvider; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationProvider; import org.springframework.security.oauth2.server.authorization.web.authentication.DelegatingAuthenticationConverter; +import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AccessTokenResponseAuthenticationSuccessHandler; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeAuthenticationConverter; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ClientCredentialsAuthenticationConverter; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2DeviceCodeAuthenticationConverter; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ErrorAuthenticationFailureHandler; import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2RefreshTokenAuthenticationConverter; -import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AccessTokenResponseAuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationConverter; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandler.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandler.java index 56b9a9b8..5a29aed2 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandler.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandler.java @@ -23,12 +23,18 @@ import java.util.function.Consumer; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.core.*; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.oauth2.core.OAuth2ErrorCodes; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationContext; @@ -42,20 +48,19 @@ import org.springframework.util.CollectionUtils; * and returning the {@link OAuth2AccessTokenResponse Access Token Response}. * * @author Dmitriy Dubson + * @since 1.3 * @see AuthenticationSuccessHandler * @see OAuth2AccessTokenResponseHttpMessageConverter - * @since 1.3 */ public final class OAuth2AccessTokenResponseAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private final Log logger = LogFactory.getLog(getClass()); - private final HttpMessageConverter accessTokenResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); - private Consumer accessTokenResponseCustomizer; @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { if (!(authentication instanceof OAuth2AccessTokenAuthenticationToken accessTokenAuthentication)) { if (this.logger.isErrorEnabled()) { this.logger.error(Authentication.class.getSimpleName() + " must be of type " + @@ -112,4 +117,5 @@ public final class OAuth2AccessTokenResponseAuthenticationSuccessHandler impleme Assert.notNull(accessTokenResponseCustomizer, "accessTokenResponseCustomizer cannot be null"); this.accessTokenResponseCustomizer = accessTokenResponseCustomizer; } + } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTest.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTests.java similarity index 78% rename from oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTest.java rename to oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTests.java index 5be56d49..1d253043 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTest.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AccessTokenAuthenticationContextTests.java @@ -15,17 +15,16 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; - import org.junit.jupiter.api.Test; + import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; -import java.security.Principal; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -34,12 +33,14 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; * * @author Dmitriy Dubson */ -public class OAuth2AccessTokenAuthenticationContextTest { +public class OAuth2AccessTokenAuthenticationContextTests { private final RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); private final OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(this.registeredClient).build(); - private final Authentication principal = this.authorization.getAttribute(Principal.class.getName()); - private final OAuth2AccessTokenAuthenticationToken accessTokenAuthenticationToken = new OAuth2AccessTokenAuthenticationToken(registeredClient, principal, - authorization.getAccessToken().getToken(), authorization.getRefreshToken().getToken()); + private OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( + this.registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, this.registeredClient.getClientSecret()); + private final OAuth2AccessTokenAuthenticationToken accessTokenAuthenticationToken = + new OAuth2AccessTokenAuthenticationToken(this.registeredClient, this.clientPrincipal, + this.authorization.getAccessToken().getToken(), this.authorization.getRefreshToken().getToken()); @Test public void withWhenAuthenticationNullThenThrowIllegalArgumentException() { @@ -54,12 +55,14 @@ public class OAuth2AccessTokenAuthenticationContextTest { OAuth2AccessTokenAuthenticationContext.with(this.accessTokenAuthenticationToken); assertThatThrownBy(() -> builder.accessTokenResponse(null)) - .isInstanceOf(IllegalArgumentException.class).hasMessage("value cannot be null"); + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("value cannot be null"); } @Test public void buildWhenAllValuesProvidedThenAllValuesAreSet() { - OAuth2AccessTokenResponse.Builder accessTokenResponseBuilder = OAuth2AccessTokenResponse.withToken(this.accessTokenAuthenticationToken.getAccessToken().getTokenValue()); + OAuth2AccessTokenResponse.Builder accessTokenResponseBuilder = + OAuth2AccessTokenResponse.withToken(this.accessTokenAuthenticationToken.getAccessToken().getTokenValue()); OAuth2AccessTokenAuthenticationContext context = OAuth2AccessTokenAuthenticationContext.with(this.accessTokenAuthenticationToken) .accessTokenResponse(accessTokenResponseBuilder) @@ -68,4 +71,5 @@ public class OAuth2AccessTokenAuthenticationContextTest { assertThat(context.getAuthentication()).isEqualTo(this.accessTokenAuthenticationToken); assertThat(context.getAccessTokenResponse()).isEqualTo(accessTokenResponseBuilder); } + } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests.java index d29ac4a9..fd700c81 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests.java @@ -15,12 +15,19 @@ */ package org.springframework.security.oauth2.server.authorization.web.authentication; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + import org.junit.jupiter.api.Test; + import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.OAuth2AccessToken; @@ -29,29 +36,16 @@ import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationContext; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.function.Consumer; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.within; /** * Tests for {@link OAuth2AccessTokenResponseAuthenticationSuccessHandler}. @@ -60,14 +54,12 @@ import static org.assertj.core.api.Assertions.within; */ public class OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests { private final RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); - private final HttpMessageConverter accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); - private final OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken( this.registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, this.registeredClient.getClientSecret()); - - private final OAuth2AccessTokenResponseAuthenticationSuccessHandler authenticationSuccessHandler = new OAuth2AccessTokenResponseAuthenticationSuccessHandler(); + private final OAuth2AccessTokenResponseAuthenticationSuccessHandler authenticationSuccessHandler = + new OAuth2AccessTokenResponseAuthenticationSuccessHandler(); @Test public void setAccessTokenResponseCustomizerWhenNullThenThrowIllegalArgumentException() { @@ -79,39 +71,40 @@ public class OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests { } @Test - public void onAuthenticationSuccessWhenProvidedRequestResponseAndAuthThenWritesAccessTokenToHttpResponse() throws Exception { + public void onAuthenticationSuccessWhenAuthenticationProvidedThenAccessTokenResponse() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); - Instant issuedAt = Instant.now(); - Instant expiresAt = issuedAt.plusSeconds(300); - OAuth2Authorization testAuthorization = TestOAuth2Authorizations.authorization(this.registeredClient).build(); + OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(this.registeredClient).build(); + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); Map additionalParameters = Collections.singletonMap("param1", "value1"); - Authentication authentication = new OAuth2AccessTokenAuthenticationToken(this.registeredClient, clientPrincipal, - testAuthorization.getAccessToken().getToken(), testAuthorization.getRefreshToken().getToken(), - additionalParameters); + Authentication authentication = new OAuth2AccessTokenAuthenticationToken( + this.registeredClient, this.clientPrincipal, accessToken, refreshToken, additionalParameters); this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authentication); OAuth2AccessTokenResponse accessTokenResponse = readAccessTokenResponse(response); - assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo("access-token"); - assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER); - assertThat(accessTokenResponse.getAccessToken().getIssuedAt()).isCloseTo(issuedAt, within(2, ChronoUnit.SECONDS)); - assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isCloseTo(expiresAt, within(2, ChronoUnit.SECONDS)); + assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo(accessToken.getTokenValue()); + assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(accessToken.getTokenType()); + assertThat(accessTokenResponse.getAccessToken().getIssuedAt()).isBetween( + accessToken.getIssuedAt().minusSeconds(1), accessToken.getIssuedAt().plusSeconds(1)); + assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween( + accessToken.getExpiresAt().minusSeconds(1), accessToken.getExpiresAt().plusSeconds(1)); assertThat(accessTokenResponse.getRefreshToken()).isNotNull(); - assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo("refresh-token"); + assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo(refreshToken.getTokenValue()); assertThat(accessTokenResponse.getAdditionalParameters()).containsExactlyInAnyOrderEntriesOf( Map.of("param1", "value1") ); } @Test - public void onAuthenticationSuccessWhenAuthenticationIsNotInstanceOfOAuth2AccessTokenAuthenticationTokenThenThrowOAuth2AuthenticationException() { + public void onAuthenticationSuccessWhenInvalidAuthenticationTypeThenThrowOAuth2AuthenticationException() { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); assertThatThrownBy(() -> - this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, Set.of(), Map.of()))) + this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, new TestingAuthenticationToken(this.clientPrincipal, null))) .isInstanceOf(OAuth2AuthenticationException.class) .extracting(ex -> ((OAuth2AuthenticationException) ex).getError()) .extracting("errorCode") @@ -119,48 +112,38 @@ public class OAuth2AccessTokenResponseAuthenticationSuccessHandlerTests { } @Test - public void onAuthenticationSuccessWhenAccessTokenResponseIsCustomizedViaAccessTokenResponseCustomizerThenResponseHasCustomizedFields() throws Exception { + public void onAuthenticationSuccessWhenAccessTokenResponseCustomizerSetThenAccessTokenResponseCustomized() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); - OAuth2AuthorizationService authorizationService = new InMemoryOAuth2AuthorizationService(); - OAuth2Authorization testAuthorization = TestOAuth2Authorizations.authorization(this.registeredClient).build(); - authorizationService.save(testAuthorization); - Instant issuedAt = Instant.now(); - Instant expiresAt = issuedAt.plusSeconds(300); - OAuth2AccessToken accessToken = testAuthorization.getAccessToken().getToken(); - OAuth2RefreshToken refreshToken = testAuthorization.getRefreshToken().getToken(); + OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(this.registeredClient).build(); + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); Map additionalParameters = Collections.singletonMap("param1", "value1"); - Authentication authentication = new OAuth2AccessTokenAuthenticationToken(this.registeredClient, clientPrincipal, accessToken, refreshToken, additionalParameters); + Authentication authentication = new OAuth2AccessTokenAuthenticationToken( + this.registeredClient, this.clientPrincipal, accessToken, refreshToken, additionalParameters); - Consumer accessTokenResponseCustomizer = (OAuth2AccessTokenAuthenticationContext authenticationContext) -> { - OAuth2AccessTokenAuthenticationToken authenticationToken = authenticationContext.getAuthentication(); - OAuth2AccessTokenResponse.Builder accessTokenResponse = authenticationContext.getAccessTokenResponse(); - OAuth2Authorization authorization = authorizationService.findByToken( - authenticationToken.getAccessToken().getTokenValue(), - OAuth2TokenType.ACCESS_TOKEN - ); - Map customParams = Map.of( - "authorization_id", authorization.getId(), - "registered_client_id", authorization.getRegisteredClientId() - ); - Map allParams = new HashMap<>(authenticationToken.getAdditionalParameters()); - allParams.putAll(customParams); - accessTokenResponse.additionalParameters(allParams); + Consumer accessTokenResponseCustomizer = (authenticationContext) -> { + OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = authenticationContext.getAuthentication(); + Map additionalParams = new HashMap<>(accessTokenAuthentication.getAdditionalParameters()); + additionalParams.put("authorization_id", authorization.getId()); + authenticationContext.getAccessTokenResponse().additionalParameters(additionalParams); }; - this.authenticationSuccessHandler.setAccessTokenResponseCustomizer(accessTokenResponseCustomizer); + this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authentication); OAuth2AccessTokenResponse accessTokenResponse = readAccessTokenResponse(response); - assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo("access-token"); - assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER); - assertThat(accessTokenResponse.getAccessToken().getIssuedAt()).isCloseTo(issuedAt, within(2, ChronoUnit.SECONDS)); - assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isCloseTo(expiresAt, within(2, ChronoUnit.SECONDS)); + assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo(accessToken.getTokenValue()); + assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(accessToken.getTokenType()); + assertThat(accessTokenResponse.getAccessToken().getIssuedAt()).isBetween( + accessToken.getIssuedAt().minusSeconds(1), accessToken.getIssuedAt().plusSeconds(1)); + assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween( + accessToken.getExpiresAt().minusSeconds(1), accessToken.getExpiresAt().plusSeconds(1)); assertThat(accessTokenResponse.getRefreshToken()).isNotNull(); - assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo("refresh-token"); + assertThat(accessTokenResponse.getRefreshToken().getTokenValue()).isEqualTo(refreshToken.getTokenValue()); assertThat(accessTokenResponse.getAdditionalParameters()).containsExactlyInAnyOrderEntriesOf( - Map.of("param1", "value1", "authorization_id", "id", "registered_client_id", "registration-1") + Map.of("param1", "value1", "authorization_id", "id") ); }