diff --git a/docs/modules/ROOT/pages/core-model-components.adoc b/docs/modules/ROOT/pages/core-model-components.adoc index 03032ce43..6c62f0adc 100644 --- a/docs/modules/ROOT/pages/core-model-components.adoc +++ b/docs/modules/ROOT/pages/core-model-components.adoc @@ -393,6 +393,7 @@ The following example shows how to register an `OAuth2TokenGenerator` `@Bean`: public OAuth2TokenGenerator tokenGenerator() { JwtEncoder jwtEncoder = ... JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); return new DelegatingOAuth2TokenGenerator( @@ -441,6 +442,7 @@ The following example shows how to implement an `OAuth2TokenCustomizer tokenGenerator() { JwtEncoder jwtEncoder = ... JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); accessTokenGenerator.setAccessTokenCustomizer(accessTokenCustomizer()); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); @@ -473,6 +475,7 @@ The following example shows how to implement an `OAuth2TokenCustomizer tokenGenerator() { JwtEncoder jwtEncoder = ... JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(jwtCustomizer()); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); diff --git a/docs/src/main/java/sample/extgrant/SecurityConfig.java b/docs/src/main/java/sample/extgrant/SecurityConfig.java index 1044363b6..4424e6ce0 100644 --- a/docs/src/main/java/sample/extgrant/SecurityConfig.java +++ b/docs/src/main/java/sample/extgrant/SecurityConfig.java @@ -15,6 +15,7 @@ */ package sample.extgrant; +import java.time.Clock; import java.util.UUID; import com.nimbusds.jose.jwk.source.JWKSource; @@ -100,6 +101,7 @@ OAuth2AuthorizationService authorizationService() { @Bean OAuth2TokenGenerator tokenGenerator(JWKSource jwkSource) { JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource)); + jwtGenerator.setClock(Clock.systemUTC()); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); return new DelegatingOAuth2TokenGenerator( diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java index dd9bf859b..f8d5c2a72 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java @@ -15,6 +15,7 @@ */ package org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers; +import java.time.Clock; import java.util.Map; import com.nimbusds.jose.jwk.source.JWKSource; @@ -128,6 +129,7 @@ private static JwtGenerator getJwtGenerator(HttpSecurity httpSecurity) { JwtEncoder jwtEncoder = getJwtEncoder(httpSecurity); if (jwtEncoder != null) { jwtGenerator = new JwtGenerator(jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(getJwtCustomizer(httpSecurity)); httpSecurity.setSharedObject(JwtGenerator.class, jwtGenerator); } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java index 249c86e3b..580a8774f 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java @@ -15,6 +15,7 @@ */ package org.springframework.security.oauth2.server.authorization.token; +import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Collections; @@ -61,6 +62,7 @@ public final class JwtGenerator implements OAuth2TokenGenerator { private final JwtEncoder jwtEncoder; + private Clock clock; private OAuth2TokenCustomizer jwtCustomizer; @@ -94,7 +96,7 @@ public Jwt generate(OAuth2TokenContext context) { } RegisteredClient registeredClient = context.getRegisteredClient(); - Instant issuedAt = Instant.now(); + Instant issuedAt = clock.instant(); Instant expiresAt; JwsAlgorithm jwsAlgorithm = SignatureAlgorithm.RS256; if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) { @@ -207,4 +209,8 @@ public void setJwtCustomizer(OAuth2TokenCustomizer jwtCustom this.jwtCustomizer = jwtCustomizer; } + public void setClock(Clock clock) { + this.clock = clock; + } + } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java index ed13047e4..bbdd4baf4 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java @@ -19,6 +19,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; +import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -133,6 +134,7 @@ public void setUp() { this.jwtEncoder = mock(JwtEncoder.class); this.jwtCustomizer = mock(OAuth2TokenCustomizer.class); JwtGenerator jwtGenerator = new JwtGenerator(this.jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(this.jwtCustomizer); this.accessTokenCustomizer = mock(OAuth2TokenCustomizer.class); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java index 6ad95f50a..29a6b494a 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java @@ -15,6 +15,7 @@ */ package org.springframework.security.oauth2.server.authorization.authentication; +import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Collections; @@ -105,6 +106,7 @@ public void setUp() { this.jwtEncoder = mock(JwtEncoder.class); this.jwtCustomizer = mock(OAuth2TokenCustomizer.class); JwtGenerator jwtGenerator = new JwtGenerator(this.jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(this.jwtCustomizer); this.accessTokenCustomizer = mock(OAuth2TokenCustomizer.class); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java index 32eb57ed7..e4d330c0d 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java @@ -16,6 +16,7 @@ package org.springframework.security.oauth2.server.authorization.authentication; import java.security.Principal; +import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Collections; @@ -120,6 +121,7 @@ public void setUp() { given(this.jwtEncoder.encode(any())).willReturn(createJwt(Collections.singleton("scope1"))); this.jwtCustomizer = mock(OAuth2TokenCustomizer.class); JwtGenerator jwtGenerator = new JwtGenerator(this.jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(this.jwtCustomizer); this.accessTokenCustomizer = mock(OAuth2TokenCustomizer.class); OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java index 4d8b1d678..61aec491d 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.security.Principal; import java.text.MessageFormat; +import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Arrays; @@ -1234,6 +1235,7 @@ JwtEncoder jwtEncoder() { @Bean OAuth2TokenGenerator tokenGenerator() { JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder()); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(jwtCustomizer()); OAuth2TokenGenerator refreshTokenGenerator = new CustomRefreshTokenGenerator(); return new DelegatingOAuth2TokenGenerator(jwtGenerator, refreshTokenGenerator); @@ -1296,6 +1298,7 @@ JwtEncoder jwtEncoder() { @Bean OAuth2TokenGenerator tokenGenerator() { JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder()); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(jwtCustomizer()); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); OAuth2TokenGenerator delegatingTokenGenerator = new DelegatingOAuth2TokenGenerator( diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java index cd4de9ffe..3b69e26e0 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java @@ -20,6 +20,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.Principal; +import java.time.Clock; import java.util.Base64; import java.util.HashSet; import java.util.List; @@ -720,6 +721,7 @@ SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) th @Bean OAuth2TokenGenerator tokenGenerator() { JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource())); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(jwtCustomizer()); OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); OAuth2TokenGenerator delegatingTokenGenerator = new DelegatingOAuth2TokenGenerator( @@ -761,6 +763,7 @@ SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) th @Bean OAuth2TokenGenerator tokenGenerator() { JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource())); + jwtGenerator.setClock(Clock.systemUTC()); jwtGenerator.setJwtCustomizer(jwtCustomizer()); OAuth2TokenGenerator refreshTokenGenerator = new CustomRefreshTokenGenerator(); return new DelegatingOAuth2TokenGenerator(jwtGenerator, refreshTokenGenerator); diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java index bb95c02e5..1234ebf06 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java @@ -15,6 +15,7 @@ */ package org.springframework.security.oauth2.server.authorization.oidc.authentication; +import java.time.Clock; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -108,6 +109,7 @@ public void setUp() { this.authorizationService = mock(OAuth2AuthorizationService.class); this.jwtEncoder = mock(JwtEncoder.class); JwtGenerator jwtGenerator = new JwtGenerator(this.jwtEncoder); + jwtGenerator.setClock(Clock.systemUTC()); this.tokenGenerator = spy(new OAuth2TokenGenerator() { @Override public Jwt generate(OAuth2TokenContext context) { diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java index c457cf7d1..ced0b4b26 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java @@ -16,6 +16,7 @@ package org.springframework.security.oauth2.server.authorization.token; import java.security.Principal; +import java.time.Clock; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; @@ -84,6 +85,7 @@ public void setUp() { this.jwtCustomizer = mock(OAuth2TokenCustomizer.class); this.jwtGenerator = new JwtGenerator(this.jwtEncoder); this.jwtGenerator.setJwtCustomizer(this.jwtCustomizer); + this.jwtGenerator.setClock(Clock.systemUTC()); AuthorizationServerSettings authorizationServerSettings = AuthorizationServerSettings.builder() .issuer("https://provider.com") .build();