Browse Source

iYOUR_USERNAMEnjecting clock when we are generating the token

Signed-off-by: AlessandroMinoccheri <aminoccheri@inpost.it>
pull/2004/head
AlessandroMinoccheri 8 months ago
parent
commit
d32d9341cb
  1. 2
      docs/modules/ROOT/pages/core-model-components.adoc
  2. 2
      docs/src/main/java/sample/extgrant/SecurityConfig.java
  3. 2
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java
  4. 19
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java
  5. 19
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java
  6. 21
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2RefreshTokenGenerator.java
  7. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java
  8. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java
  9. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java
  10. 3
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java
  11. 3
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcTests.java
  12. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java
  13. 2
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java

2
docs/modules/ROOT/pages/core-model-components.adoc

@ -393,6 +393,7 @@ The following example shows how to register an `OAuth2TokenGenerator` `@Bean`: @@ -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<OAuth2Tok @@ -441,6 +442,7 @@ The following example shows how to implement an `OAuth2TokenCustomizer<OAuth2Tok
public OAuth2TokenGenerator<?> tokenGenerator() {
JwtEncoder jwtEncoder = ...
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
jwtGenerator.setClock(Clock.systemUTC());
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
accessTokenGenerator.setAccessTokenCustomizer(accessTokenCustomizer());
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();

2
docs/src/main/java/sample/extgrant/SecurityConfig.java

@ -15,6 +15,7 @@ @@ -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 @@ public class SecurityConfig { @@ -100,6 +101,7 @@ public class SecurityConfig {
@Bean
OAuth2TokenGenerator<?> tokenGenerator(JWKSource<SecurityContext> jwkSource) {
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource));
jwtGenerator.setClock(Clock.systemUTC());
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(

2
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2ConfigurerUtils.java

@ -15,6 +15,7 @@ @@ -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 @@ final class OAuth2ConfigurerUtils { @@ -128,6 +129,7 @@ final class OAuth2ConfigurerUtils {
JwtEncoder jwtEncoder = getJwtEncoder(httpSecurity);
if (jwtEncoder != null) {
jwtGenerator = new JwtGenerator(jwtEncoder);
jwtGenerator.setClock(Clock.systemUTC());
jwtGenerator.setJwtCustomizer(getJwtCustomizer(httpSecurity));
httpSecurity.setSharedObject(JwtGenerator.class, jwtGenerator);
}

19
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/JwtGenerator.java

@ -15,6 +15,7 @@ @@ -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 @@ import org.springframework.util.StringUtils; @@ -61,6 +62,7 @@ import org.springframework.util.StringUtils;
public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> {
private final JwtEncoder jwtEncoder;
private Clock clock = Clock.systemUTC();
private OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer;
@ -94,7 +96,7 @@ public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> { @@ -94,7 +96,7 @@ public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> {
}
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,19 @@ public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> { @@ -207,4 +209,19 @@ public final class JwtGenerator implements OAuth2TokenGenerator<Jwt> {
this.jwtCustomizer = jwtCustomizer;
}
/**
* Sets the {@link Clock} to be used by this component.
* <p>
* The provided clock must not be {@code null}.
* This allows injecting a custom clock for testing or
* adjusting time-related behavior.
*
* @param clock the {@link Clock} instance to set, must not be {@code null}
* @throws IllegalArgumentException if {@code clock} is {@code null}
*/
public void setClock(Clock clock) {
Assert.notNull(clock, "Clock must not be null");
this.clock = clock;
}
}

19
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2AccessTokenGenerator.java

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.security.oauth2.server.authorization.token;
import java.time.Clock;
import java.time.Instant;
import java.util.Base64;
import java.util.Collections;
@ -52,6 +53,7 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA @@ -52,6 +53,7 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA
private final StringKeyGenerator accessTokenGenerator = new Base64StringKeyGenerator(
Base64.getUrlEncoder().withoutPadding(), 96);
private Clock clock = Clock.systemUTC();
private OAuth2TokenCustomizer<OAuth2TokenClaimsContext> accessTokenCustomizer;
@ -71,7 +73,7 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA @@ -71,7 +73,7 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA
}
RegisteredClient registeredClient = context.getRegisteredClient();
Instant issuedAt = Instant.now();
Instant issuedAt = clock.instant();
Instant expiresAt = issuedAt.plus(registeredClient.getTokenSettings().getAccessTokenTimeToLive());
// @formatter:off
@ -156,4 +158,19 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA @@ -156,4 +158,19 @@ public final class OAuth2AccessTokenGenerator implements OAuth2TokenGenerator<OA
}
/**
* Sets the {@link Clock} to be used by this component.
* <p>
* The provided clock must not be {@code null}.
* This allows injecting a custom clock for testing or
* adjusting time-related behavior.
*
* @param clock the {@link Clock} instance to set, must not be {@code null}
* @throws IllegalArgumentException if {@code clock} is {@code null}
*/
public void setClock(Clock clock) {
Assert.notNull(clock, "Clock must not be null");
this.clock = clock;
}
}

21
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/token/OAuth2RefreshTokenGenerator.java

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.security.oauth2.server.authorization.token;
import java.time.Clock;
import java.time.Instant;
import java.util.Base64;
@ -26,6 +27,7 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod; @@ -26,6 +27,7 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.util.Assert;
/**
* An {@link OAuth2TokenGenerator} that generates an {@link OAuth2RefreshToken}.
@ -39,6 +41,7 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O @@ -39,6 +41,7 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O
private final StringKeyGenerator refreshTokenGenerator = new Base64StringKeyGenerator(
Base64.getUrlEncoder().withoutPadding(), 96);
private Clock clock = Clock.systemUTC();
@Nullable
@Override
@ -51,7 +54,8 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O @@ -51,7 +54,8 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O
return null;
}
Instant issuedAt = Instant.now();
Instant issuedAt = clock.instant();
Instant expiresAt = issuedAt.plus(context.getRegisteredClient().getTokenSettings().getRefreshTokenTimeToLive());
return new OAuth2RefreshToken(this.refreshTokenGenerator.generateKey(), issuedAt, expiresAt);
}
@ -66,4 +70,19 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O @@ -66,4 +70,19 @@ public final class OAuth2RefreshTokenGenerator implements OAuth2TokenGenerator<O
return false;
}
/**
* Sets the {@link Clock} to be used by this component.
* <p>
* The provided clock must not be {@code null}.
* This allows injecting a custom clock for testing or
* adjusting time-related behavior.
*
* @param clock the {@link Clock} instance to set, must not be {@code null}
* @throws IllegalArgumentException if {@code clock} is {@code null}
*/
public void setClock(Clock clock) {
Assert.notNull(clock, "Clock must not be null");
this.clock = clock;
}
}

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeAuthenticationProviderTests.java

@ -19,6 +19,7 @@ import java.nio.charset.StandardCharsets; @@ -19,6 +19,7 @@ import java.nio.charset.StandardCharsets;
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 class OAuth2AuthorizationCodeAuthenticationProviderTests { @@ -133,6 +134,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
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();

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java

@ -15,6 +15,7 @@ @@ -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 class OAuth2ClientCredentialsAuthenticationProviderTests { @@ -105,6 +106,7 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
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();

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2RefreshTokenAuthenticationProviderTests.java

@ -16,6 +16,7 @@ @@ -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 class OAuth2RefreshTokenAuthenticationProviderTests { @@ -120,6 +121,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
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();

3
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java

@ -21,6 +21,7 @@ import java.net.URLEncoder; @@ -21,6 +21,7 @@ import java.net.URLEncoder;
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 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -1234,6 +1235,7 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder());
jwtGenerator.setClock(Clock.systemUTC());
jwtGenerator.setJwtCustomizer(jwtCustomizer());
OAuth2TokenGenerator<OAuth2RefreshToken> refreshTokenGenerator = new CustomRefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(jwtGenerator, refreshTokenGenerator);
@ -1296,6 +1298,7 @@ public class OAuth2AuthorizationCodeGrantTests { @@ -1296,6 +1298,7 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder());
jwtGenerator.setClock(Clock.systemUTC());
jwtGenerator.setJwtCustomizer(jwtCustomizer());
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
OAuth2TokenGenerator<OAuth2Token> delegatingTokenGenerator = new DelegatingOAuth2TokenGenerator(

3
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.URLDecoder; @@ -20,6 +20,7 @@ import java.net.URLDecoder;
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 @@ public class OidcTests { @@ -720,6 +721,7 @@ public class OidcTests {
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource()));
jwtGenerator.setClock(Clock.systemUTC());
jwtGenerator.setJwtCustomizer(jwtCustomizer());
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
OAuth2TokenGenerator<OAuth2Token> delegatingTokenGenerator = new DelegatingOAuth2TokenGenerator(
@ -761,6 +763,7 @@ public class OidcTests { @@ -761,6 +763,7 @@ public class OidcTests {
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource()));
jwtGenerator.setClock(Clock.systemUTC());
jwtGenerator.setJwtCustomizer(jwtCustomizer());
OAuth2TokenGenerator<OAuth2RefreshToken> refreshTokenGenerator = new CustomRefreshTokenGenerator();
return new DelegatingOAuth2TokenGenerator(jwtGenerator, refreshTokenGenerator);

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProviderTests.java

@ -15,6 +15,7 @@ @@ -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 class OidcClientRegistrationAuthenticationProviderTests { @@ -108,6 +109,7 @@ public class OidcClientRegistrationAuthenticationProviderTests {
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<Jwt>() {
@Override
public Jwt generate(OAuth2TokenContext context) {

2
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/token/JwtGeneratorTests.java

@ -16,6 +16,7 @@ @@ -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 class JwtGeneratorTests { @@ -84,6 +85,7 @@ public class JwtGeneratorTests {
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();

Loading…
Cancel
Save