Browse Source

Add configuration for authorization code time-to-live

Closes gh-642
pull/762/merge
Gyeongwon, Do 4 years ago committed by Joe Grandja
parent
commit
303043ea78
  1. 5
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java
  2. 5
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/ConfigurationSettingNames.java
  3. 23
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/TokenSettings.java
  4. 32
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/TokenSettingsTests.java

5
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java

@ -17,7 +17,6 @@ package org.springframework.security.oauth2.server.authorization.authentication; @@ -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 @@ -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);
}

5
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/ConfigurationSettingNames.java

@ -128,6 +128,11 @@ public final class ConfigurationSettingNames { @@ -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.
*/

23
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/TokenSettings.java

@ -37,6 +37,15 @@ public final class TokenSettings extends AbstractSettings { @@ -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 { @@ -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 { @@ -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}.
*

32
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/TokenSettingsTests.java

@ -35,7 +35,8 @@ public class TokenSettingsTests { @@ -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 { @@ -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 { @@ -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");
}

Loading…
Cancel
Save