diff --git a/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java b/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java index 2725945def..83f0e52e22 100644 --- a/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java +++ b/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java @@ -16,6 +16,8 @@ */ package org.keycloak.models; +import org.keycloak.common.util.Base64; +import java.nio.charset.StandardCharsets; import java.util.UUID; /** @@ -45,6 +47,8 @@ public interface ActionTokenKeyModel { UUID getActionVerificationNonce(); default String serializeKey() { - return String.format("%s.%d.%s.%s", getUserId(), getExpiration(), getActionVerificationNonce(), getActionId()); + String userId = getUserId(); + String encodedUserId = userId == null ? "" : Base64.encodeBytes(userId.getBytes(StandardCharsets.UTF_8)); + return String.format("%s.%d.%s.%s", encodedUserId, getExpiration(), getActionVerificationNonce(), getActionId()); } } diff --git a/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java b/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java index 9723005a85..96b817e2f0 100644 --- a/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java +++ b/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java @@ -16,11 +16,17 @@ */ package org.keycloak.authentication.actiontoken; +import org.keycloak.common.util.Base64; import org.keycloak.models.ActionTokenKeyModel; import org.keycloak.representations.JsonWebToken; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; /** * @@ -63,16 +69,24 @@ public class DefaultActionTokenKey extends JsonWebToken implements ActionTokenKe return actionVerificationNonce; } + private static final Pattern DOT = Pattern.compile("\\."); + public static DefaultActionTokenKey from(String serializedKey) { if (serializedKey == null) { return null; } - String[] parsed = serializedKey.split("\\.", 4); + String[] parsed = DOT.split(serializedKey, 4); if (parsed.length != 4) { return null; } - return new DefaultActionTokenKey(parsed[0], parsed[3], Integer.parseInt(parsed[1]), UUID.fromString(parsed[2])); + String userId; + try { + userId = new String(Base64.decode(parsed[0]), StandardCharsets.UTF_8); + } catch (IOException ex) { + userId = parsed[0]; + } + return new DefaultActionTokenKey(userId, parsed[3], Integer.parseInt(parsed[1]), UUID.fromString(parsed[2])); } }