Add configuration for authorization code time-to-live
Closes gh-642
This commit is contained in:
committed by
Joe Grandja
parent
3f5e7c793b
commit
303043ea78
@@ -17,7 +17,6 @@ package org.springframework.security.oauth2.server.authorization.authentication;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -565,8 +564,10 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen
|
||||
!OAuth2ParameterNames.CODE.equals(context.getTokenType().getValue())) {
|
||||
return null;
|
||||
}
|
||||
RegisteredClient registeredClient = context.getRegisteredClient();
|
||||
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = issuedAt.plus(5, ChronoUnit.MINUTES); // TODO Allow configuration for authorization code time-to-live
|
||||
Instant expiresAt = issuedAt.plus(registeredClient.getTokenSettings().getAuthorizationCodeTimeToLive());
|
||||
return new OAuth2AuthorizationCode(this.authorizationCodeGenerator.generateKey(), issuedAt, expiresAt);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,11 @@ public final class ConfigurationSettingNames {
|
||||
public static final class Token {
|
||||
private static final String TOKEN_SETTINGS_NAMESPACE = SETTINGS_NAMESPACE.concat("token.");
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an authorization code.
|
||||
*/
|
||||
public static final String AUTHORIZATION_CODE_TIME_TO_LIVE = TOKEN_SETTINGS_NAMESPACE.concat("authorization-code-time-to-live");
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an access token.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,15 @@ public final class TokenSettings extends AbstractSettings {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time-to-live for an authorization code. The default is 5 minutes.
|
||||
*
|
||||
* @return the time-to-live for an authorization code
|
||||
*/
|
||||
public Duration getAuthorizationCodeTimeToLive() {
|
||||
return getSetting(ConfigurationSettingNames.Token.AUTHORIZATION_CODE_TIME_TO_LIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time-to-live for an access token. The default is 5 minutes.
|
||||
*
|
||||
@@ -91,6 +100,7 @@ public final class TokenSettings extends AbstractSettings {
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.authorizationCodeTimeToLive(Duration.ofMinutes(5))
|
||||
.accessTokenTimeToLive(Duration.ofMinutes(5))
|
||||
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
|
||||
.reuseRefreshTokens(true)
|
||||
@@ -118,6 +128,19 @@ public final class TokenSettings extends AbstractSettings {
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an access token. Must be greater than {@code Duration.ZERO}.
|
||||
* A maximum authorization code lifetime of 10 minutes is RECOMMENDED
|
||||
*
|
||||
* @param authorizationCodeTimeToLive the time-to-live for an authorization code
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder authorizationCodeTimeToLive(Duration authorizationCodeTimeToLive) {
|
||||
Assert.notNull(authorizationCodeTimeToLive, "authorizationCodeTimeToLive cannot be null");
|
||||
Assert.isTrue(authorizationCodeTimeToLive.getSeconds() > 0, "authorizationCodeTimeToLive must be greater than Duration.ZERO");
|
||||
return setting(ConfigurationSettingNames.Token.AUTHORIZATION_CODE_TIME_TO_LIVE, authorizationCodeTimeToLive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an access token. Must be greater than {@code Duration.ZERO}.
|
||||
*
|
||||
|
||||
@@ -35,7 +35,8 @@ public class TokenSettingsTests {
|
||||
@Test
|
||||
public void buildWhenDefaultThenDefaultsAreSet() {
|
||||
TokenSettings tokenSettings = TokenSettings.builder().build();
|
||||
assertThat(tokenSettings.getSettings()).hasSize(5);
|
||||
assertThat(tokenSettings.getSettings()).hasSize(6);
|
||||
assertThat(tokenSettings.getAuthorizationCodeTimeToLive()).isEqualTo(Duration.ofMinutes(5));
|
||||
assertThat(tokenSettings.getAccessTokenTimeToLive()).isEqualTo(Duration.ofMinutes(5));
|
||||
assertThat(tokenSettings.getAccessTokenFormat()).isEqualTo(OAuth2TokenFormat.SELF_CONTAINED);
|
||||
assertThat(tokenSettings.isReuseRefreshTokens()).isTrue();
|
||||
@@ -43,6 +44,33 @@ public class TokenSettingsTests {
|
||||
assertThat(tokenSettings.getIdTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authorizationCodeTimeToLiveWhenProvidedThenSet() {
|
||||
Duration authorizationCodeTimeToLive = Duration.ofMinutes(10);
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.authorizationCodeTimeToLive(authorizationCodeTimeToLive)
|
||||
.build();
|
||||
assertThat(tokenSettings.getAuthorizationCodeTimeToLive()).isEqualTo(authorizationCodeTimeToLive);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authorizationCodeTimeToLiveWhenNullOrZeroOrNegativeThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> TokenSettings.builder().authorizationCodeTimeToLive(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("authorizationCodeTimeToLive cannot be null");
|
||||
|
||||
assertThatThrownBy(() -> TokenSettings.builder().authorizationCodeTimeToLive(Duration.ZERO))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("authorizationCodeTimeToLive must be greater than Duration.ZERO");
|
||||
|
||||
assertThatThrownBy(() -> TokenSettings.builder().authorizationCodeTimeToLive(Duration.ofSeconds(-10)))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("authorizationCodeTimeToLive must be greater than Duration.ZERO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessTokenTimeToLiveWhenProvidedThenSet() {
|
||||
Duration accessTokenTimeToLive = Duration.ofMinutes(10);
|
||||
@@ -136,7 +164,7 @@ public class TokenSettingsTests {
|
||||
.setting("name1", "value1")
|
||||
.settings(settings -> settings.put("name2", "value2"))
|
||||
.build();
|
||||
assertThat(tokenSettings.getSettings()).hasSize(7);
|
||||
assertThat(tokenSettings.getSettings()).hasSize(8);
|
||||
assertThat(tokenSettings.<String>getSetting("name1")).isEqualTo("value1");
|
||||
assertThat(tokenSettings.<String>getSetting("name2")).isEqualTo("value2");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user