keycloak-aplcache

Details

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 cf9d7d0..2725945 100644
--- a/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/ActionTokenKeyModel.java
@@ -43,4 +43,8 @@ public interface ActionTokenKeyModel {
      * @return Single-use random value used for verification whether the relevant action is allowed.
      */
     UUID getActionVerificationNonce();
+
+    default String serializeKey() {
+        return String.format("%s.%d.%s.%s", getUserId(), getExpiration(), getActionVerificationNonce(), getActionId());
+    }
 }
diff --git a/services/src/main/java/org/keycloak/authentication/actiontoken/ActionTokenHandler.java b/services/src/main/java/org/keycloak/authentication/actiontoken/ActionTokenHandler.java
index b61c9c0..4f98070 100644
--- a/services/src/main/java/org/keycloak/authentication/actiontoken/ActionTokenHandler.java
+++ b/services/src/main/java/org/keycloak/authentication/actiontoken/ActionTokenHandler.java
@@ -17,6 +17,7 @@
 package org.keycloak.authentication.actiontoken;
 
 import org.keycloak.TokenVerifier.Predicate;
+import org.keycloak.common.VerificationException;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
 import org.keycloak.provider.Provider;
@@ -93,7 +94,7 @@ public interface ActionTokenHandler<T extends JsonWebToken> extends Provider {
      * @param tokenContext
      * @return
      */
-    AuthenticationSessionModel startFreshAuthenticationSession(T token, ActionTokenContext<T> tokenContext);
+    AuthenticationSessionModel startFreshAuthenticationSession(T token, ActionTokenContext<T> tokenContext) throws VerificationException;
 
     /**
      * Returns {@code true} when the token can be used repeatedly to invoke the action, {@code false} when the token
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 cc4ba32..9723005 100644
--- a/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java
+++ b/services/src/main/java/org/keycloak/authentication/actiontoken/DefaultActionTokenKey.java
@@ -63,10 +63,6 @@ public class DefaultActionTokenKey extends JsonWebToken implements ActionTokenKe
         return actionVerificationNonce;
     }
 
-    public String serializeKey() {
-        return String.format("%s.%d.%s.%s", getUserId(), getExpiration(), getActionVerificationNonce(), getActionId());
-    }
-
     public static DefaultActionTokenKey from(String serializedKey) {
         if (serializedKey == null) {
             return null;
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 5e8b0fe..f6dd8a4 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -42,6 +42,7 @@ import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
 import org.keycloak.exceptions.TokenNotActiveException;
+import org.keycloak.models.ActionTokenKeyModel;
 import org.keycloak.models.AuthenticationFlowModel;
 import org.keycloak.models.AuthenticatedClientSessionModel;
 import org.keycloak.models.ClientModel;
@@ -406,7 +407,7 @@ public class LoginActionsService {
         return handleActionToken(key, execution, clientId);
     }
 
-    protected <T extends DefaultActionTokenKey> Response handleActionToken(String tokenString, String execution, String clientId) {
+    protected <T extends JsonWebToken & ActionTokenKeyModel> Response handleActionToken(String tokenString, String execution, String clientId) {
         T token;
         ActionTokenHandler<T> handler;
         ActionTokenContext<T> tokenContext;
@@ -556,7 +557,6 @@ public class LoginActionsService {
         }
     }
 
-
     private <T extends JsonWebToken> ActionTokenHandler<T> resolveActionTokenHandler(String actionId) throws VerificationException {
         if (actionId == null) {
             throw new VerificationException("Action token operation not set");
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsServiceChecks.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsServiceChecks.java
index b9031cb..e330d29 100644
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsServiceChecks.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsServiceChecks.java
@@ -18,7 +18,6 @@ package org.keycloak.services.resources;
 
 import org.keycloak.TokenVerifier.Predicate;
 import org.keycloak.authentication.AuthenticationProcessor;
-import org.keycloak.authentication.actiontoken.DefaultActionTokenKey;
 import org.keycloak.authentication.ExplainedVerificationException;
 import org.keycloak.authentication.actiontoken.ActionTokenContext;
 import org.keycloak.authentication.actiontoken.ExplainedTokenVerificationException;
@@ -152,7 +151,7 @@ public class LoginActionsServiceChecks {
      *  Verifies whether the user given by ID both exists in the current realm. If yes,
      *  it optionally also injects the user using the given function (e.g. into session context).
      */
-    public static <T extends DefaultActionTokenKey> void checkIsUserValid(T token, ActionTokenContext<T> context) throws VerificationException {
+    public static <T extends JsonWebToken & ActionTokenKeyModel> void checkIsUserValid(T token, ActionTokenContext<T> context) throws VerificationException {
         try {
             checkIsUserValid(context.getSession(), context.getRealm(), token.getUserId(), context.getAuthenticationSession()::setAuthenticatedUser);
         } catch (ExplainedVerificationException ex) {
@@ -297,7 +296,7 @@ public class LoginActionsServiceChecks {
         return true;
     }
 
-    public static <T extends DefaultActionTokenKey> void checkTokenWasNotUsedYet(T token, ActionTokenContext<T> context) throws VerificationException {
+    public static <T extends JsonWebToken & ActionTokenKeyModel> void checkTokenWasNotUsedYet(T token, ActionTokenContext<T> context) throws VerificationException {
         ActionTokenStoreProvider actionTokenStore = context.getSession().getProvider(ActionTokenStoreProvider.class);
 
         if (actionTokenStore.get(token) != null) {