From 5e623f42d49d09261b75fe19a4f6e37ab3f7344e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niko=20Ko=CC=88bler?= Date: Thu, 21 Dec 2023 23:47:56 +0100 Subject: [PATCH] add the exp claim to the backchannel logout token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is now, as of Dec 15th 2023, part of the OIDC Backchannel Logout spec, chapter 2.4. As of chapter 4, the logout token should have a short expiration time, preferably at most two minutes in the future. So we set the expiration to this time. resolves #25753 Signed-off-by: Niko Köbler --- .../main/java/org/keycloak/jose/jws/DefaultTokenManager.java | 3 +++ .../test/java/org/keycloak/testsuite/util/LogoutTokenUtil.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/services/src/main/java/org/keycloak/jose/jws/DefaultTokenManager.java b/services/src/main/java/org/keycloak/jose/jws/DefaultTokenManager.java index fa91d5dc3c1..4fa4dc9e97c 100644 --- a/services/src/main/java/org/keycloak/jose/jws/DefaultTokenManager.java +++ b/services/src/main/java/org/keycloak/jose/jws/DefaultTokenManager.java @@ -19,6 +19,7 @@ package org.keycloak.jose.jws; import org.jboss.logging.Logger; import org.keycloak.Token; import org.keycloak.TokenCategory; +import org.keycloak.common.util.Time; import org.keycloak.crypto.Algorithm; import org.keycloak.crypto.CekManagementProvider; import org.keycloak.crypto.ClientSignatureVerifierProvider; @@ -54,6 +55,7 @@ import org.keycloak.util.TokenUtil; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.Key; +import java.time.Duration; import java.util.Comparator; import java.util.Optional; import java.util.function.BiConsumer; @@ -327,6 +329,7 @@ public class DefaultTokenManager implements TokenManager { LogoutToken token = new LogoutToken(); token.id(KeycloakModelUtils.generateId()); token.issuedNow(); + token.exp(Time.currentTime() + Duration.ofMinutes(2).getSeconds()); token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER)); token.putEvents(TokenUtil.TOKEN_BACKCHANNEL_LOGOUT_EVENT, JsonSerialization.createObjectNode()); token.addAudience(client.getClientId()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/LogoutTokenUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/LogoutTokenUtil.java index 201e5792985..84f0616fe2e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/LogoutTokenUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/LogoutTokenUtil.java @@ -2,6 +2,7 @@ package org.keycloak.testsuite.util; import org.keycloak.OAuth2Constants; import org.keycloak.common.util.Base64Url; +import org.keycloak.common.util.Time; import org.keycloak.crypto.JavaAlgorithm; import org.keycloak.jose.jws.Algorithm; import org.keycloak.jose.jws.JWSHeader; @@ -15,6 +16,7 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Signature; import java.security.SignatureException; +import java.time.Duration; import java.util.HashMap; import java.util.UUID; @@ -35,6 +37,7 @@ public class LogoutTokenUtil { logoutToken.issuer(issuer); logoutToken.id(UUID.randomUUID().toString()); logoutToken.issuedNow(); + logoutToken.exp(Time.currentTime() + Duration.ofMinutes(2).getSeconds()); logoutToken.audience(clientId); String logoutTokenPayloadEncoded = Base64Url.encode(JsonSerialization.writeValueAsBytes(logoutToken));