Allow expired ID tokens on RP-initiated logout

Closes gh-1440
This commit is contained in:
Joe Grandja
2023-12-12 07:05:58 -05:00
parent 59d510b3ab
commit fb9a13b0ff
2 changed files with 26 additions and 2 deletions

View File

@@ -97,7 +97,8 @@ public final class OidcLogoutAuthenticationProvider implements AuthenticationPro
}
OAuth2Authorization.Token<OidcIdToken> authorizedIdToken = authorization.getToken(OidcIdToken.class);
if (!authorizedIdToken.isActive()) {
if (authorizedIdToken.isInvalidated() ||
authorizedIdToken.isBeforeUse()) { // Expired ID Token should be accepted
throwError(OAuth2ErrorCodes.INVALID_TOKEN, "id_token_hint");
}

View File

@@ -30,6 +30,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
@@ -134,7 +135,7 @@ public class OidcLogoutAuthenticationProviderTests {
}
@Test
public void authenticateWhenIdTokenNotActiveThenThrowOAuth2AuthenticationException() {
public void authenticateWhenIdTokenInvalidatedThenThrowOAuth2AuthenticationException() {
TestingAuthenticationToken principal = new TestingAuthenticationToken("principal", "credentials");
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
OidcIdToken idToken = OidcIdToken.withTokenValue("id-token")
@@ -501,6 +502,28 @@ public class OidcLogoutAuthenticationProviderTests {
.expiresAt(Instant.now().plusSeconds(60).truncatedTo(ChronoUnit.MILLIS))
.claim("sid", createHash(sessionId))
.build();
authenticateValidIdToken(principal, registeredClient, sessionId, idToken);
}
// gh-1440
@Test
public void authenticateWhenValidExpiredIdTokenThenAuthenticated() throws Exception {
TestingAuthenticationToken principal = new TestingAuthenticationToken("principal", "credentials");
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
String sessionId = "session-1";
OidcIdToken idToken = OidcIdToken.withTokenValue("id-token")
.issuer("https://provider.com")
.subject(principal.getName())
.audience(Collections.singleton(registeredClient.getClientId()))
.issuedAt(Instant.now().minusSeconds(60).truncatedTo(ChronoUnit.MILLIS))
.expiresAt(Instant.now().minusSeconds(30).truncatedTo(ChronoUnit.MILLIS)) // Expired
.claim("sid", createHash(sessionId))
.build();
authenticateValidIdToken(principal, registeredClient, sessionId, idToken);
}
private void authenticateValidIdToken(Authentication principal, RegisteredClient registeredClient,
String sessionId, OidcIdToken idToken) {
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
.principalName(principal.getName())
.token(idToken,