diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProvider.java
deleted file mode 100644
index ff5f130d7d1..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProvider.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.CodeToTokenStoreProvider;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import org.keycloak.connections.infinispan.InfinispanUtil;
-
-/**
- * @author Marek Posolda
- */
-public class InfinispanCodeToTokenStoreProvider implements CodeToTokenStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanCodeToTokenStoreProvider.class);
-
- private final Supplier> codeCache;
- private final KeycloakSession session;
-
- public InfinispanCodeToTokenStoreProvider(KeycloakSession session, Supplier> actionKeyCache) {
- this.session = session;
- this.codeCache = actionKeyCache;
- }
-
-
- @Override
- public void put(UUID codeId, int lifespanSeconds, Map codeData) {
- ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(codeData);
-
- try {
- BasicCache cache = codeCache.get();
- long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanSeconds));
- cache.put(codeId, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when adding code %s", codeId);
- }
-
- throw re;
- }
- }
-
-
- @Override
- public Map remove(UUID codeId) {
- try {
- BasicCache cache = codeCache.get();
- ActionTokenValueEntity existing = cache.remove(codeId);
- return existing == null ? null : existing.getNotes();
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when removing code %s", codeId);
- }
-
- return null;
- }
- }
-
-
- @Override
- public void close() {
-
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProviderFactory.java
deleted file mode 100644
index f5944ced300..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanCodeToTokenStoreProviderFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import java.util.UUID;
-import java.util.function.Supplier;
-
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.Config;
-import org.keycloak.models.CodeToTokenStoreProvider;
-import org.keycloak.models.CodeToTokenStoreProviderFactory;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;
-
-/**
- * @author Marek Posolda
- */
-public class InfinispanCodeToTokenStoreProviderFactory implements CodeToTokenStoreProviderFactory {
-
- private static final Logger LOG = Logger.getLogger(InfinispanCodeToTokenStoreProviderFactory.class);
-
- // Reuse "actionTokens" infinispan cache for now
- private volatile Supplier> codeCache;
-
- @Override
- public CodeToTokenStoreProvider create(KeycloakSession session) {
- lazyInit(session);
- return new InfinispanCodeToTokenStoreProvider(session, codeCache);
- }
-
- private void lazyInit(KeycloakSession session) {
- if (codeCache == null) {
- synchronized (this) {
- if (codeCache == null) {
- this.codeCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
- }
- }
- }
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public String getId() {
- return "infinispan";
- }
-
- @Override
- public int order() {
- return PROVIDER_PRIORITY;
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProvider.java
deleted file mode 100644
index bf43fb8192f..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProvider.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2019 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.authorization.policy.evaluation.Realm;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
-import org.keycloak.models.OAuth2DeviceUserCodeModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-/**
- * @author Hiroyuki Wada
- */
-public class InfinispanOAuth2DeviceTokenStoreProvider implements OAuth2DeviceTokenStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanOAuth2DeviceTokenStoreProvider.class);
-
- private final Supplier> codeCache;
- private final KeycloakSession session;
-
- public InfinispanOAuth2DeviceTokenStoreProvider(KeycloakSession session, Supplier> actionKeyCache) {
- this.session = session;
- this.codeCache = actionKeyCache;
- }
-
- @Override
- public OAuth2DeviceCodeModel getByDeviceCode(RealmModel realm, String deviceCode) {
- try {
- BasicCache cache = codeCache.get();
- ActionTokenValueEntity existing = cache.get(OAuth2DeviceCodeModel.createKey(deviceCode));
-
- if (existing == null) {
- return null;
- }
-
- return OAuth2DeviceCodeModel.fromCache(realm, deviceCode, existing.getNotes());
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when getting device code %s", deviceCode);
- }
-
- return null;
- }
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public void put(OAuth2DeviceCodeModel deviceCode, OAuth2DeviceUserCodeModel userCode, int lifespanSeconds) {
- ActionTokenValueEntity deviceCodeValue = new ActionTokenValueEntity(deviceCode.toMap());
- ActionTokenValueEntity userCodeValue = new ActionTokenValueEntity(userCode.serializeValue());
-
- try {
- BasicCache cache = codeCache.get();
- cache.put(deviceCode.serializeKey(), deviceCodeValue, lifespanSeconds, TimeUnit.SECONDS);
- cache.put(userCode.serializeKey(), userCodeValue, lifespanSeconds, TimeUnit.SECONDS);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when adding device code %s and user code %s",
- deviceCode.getDeviceCode(), userCode.getUserCode());
- }
- throw re;
- }
- }
-
- @Override
- public boolean isPollingAllowed(OAuth2DeviceCodeModel deviceCode) {
- try {
- BasicCache cache = codeCache.get();
- String key = deviceCode.serializePollingKey();
- ActionTokenValueEntity value = new ActionTokenValueEntity(null);
- ActionTokenValueEntity existing = cache.putIfAbsent(key, value, deviceCode.getPollingInterval(), TimeUnit.SECONDS);
- return existing == null;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when putting polling key for device code %s", deviceCode.getDeviceCode());
- }
-
- return false;
- }
- }
-
- @Override
- public OAuth2DeviceCodeModel getByUserCode(RealmModel realm, String userCode) {
- try {
- OAuth2DeviceCodeModel deviceCode = findDeviceCodeByUserCode(realm, userCode);
- if (deviceCode == null) {
- return null;
- }
-
- return deviceCode;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when getting device code by user code %s", userCode);
- }
-
- return null;
- }
- }
-
- private OAuth2DeviceCodeModel findDeviceCodeByUserCode(RealmModel realm, String userCode) throws HotRodClientException {
- BasicCache cache = codeCache.get();
- String userCodeKey = OAuth2DeviceUserCodeModel.createKey(realm, userCode);
- ActionTokenValueEntity existing = cache.get(userCodeKey);
-
- if (existing == null) {
- return null;
- }
-
- OAuth2DeviceUserCodeModel data = OAuth2DeviceUserCodeModel.fromCache(realm, userCode, existing.getNotes());
- String deviceCode = data.getDeviceCode();
-
- String deviceCodeKey = OAuth2DeviceCodeModel.createKey(deviceCode);
- ActionTokenValueEntity existingDeviceCode = cache.get(deviceCodeKey);
-
- if (existingDeviceCode == null) {
- return null;
- }
-
- return OAuth2DeviceCodeModel.fromCache(realm, deviceCode, existingDeviceCode.getNotes());
- }
-
- @Override
- public boolean approve(RealmModel realm, String userCode, String userSessionId, Map additionalParams) {
- try {
- OAuth2DeviceCodeModel deviceCode = findDeviceCodeByUserCode(realm, userCode);
- if (deviceCode == null) {
- return false;
- }
-
- OAuth2DeviceCodeModel approved = deviceCode.approve(userSessionId, additionalParams);
-
- // Update the device code with approved status
- BasicCache cache = codeCache.get();
- cache.replace(approved.serializeKey(), new ActionTokenValueEntity(approved.toMap()));
-
- return true;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when verifying device user code %s", userCode);
- }
-
- return false;
- }
- }
-
- @Override
- public boolean deny(RealmModel realm, String userCode) {
- try {
- OAuth2DeviceCodeModel deviceCode = findDeviceCodeByUserCode(realm, userCode);
- if (deviceCode == null) {
- return false;
- }
-
- OAuth2DeviceCodeModel denied = deviceCode.deny();
-
- BasicCache cache = codeCache.get();
- cache.replace(denied.serializeKey(), new ActionTokenValueEntity(denied.toMap()));
-
- return true;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when denying device user code %s", userCode);
- }
-
- return false;
- }
- }
-
- @Override
- public boolean removeDeviceCode(RealmModel realm, String deviceCode) {
- try {
- BasicCache cache = codeCache.get();
- String key = OAuth2DeviceCodeModel.createKey(deviceCode);
- ActionTokenValueEntity existing = cache.remove(key);
- return existing == null ? false : true;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when removing device code %s", deviceCode);
- }
-
- return false;
- }
- }
-
- @Override
- public boolean removeUserCode(RealmModel realm, String userCode) {
- try {
- BasicCache cache = codeCache.get();
- String key = OAuth2DeviceUserCodeModel.createKey(realm, userCode);
- ActionTokenValueEntity existing = cache.remove(key);
- return existing == null ? false : true;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when removing user code %s", userCode);
- }
-
- return false;
- }
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProviderFactory.java
deleted file mode 100644
index 3d628f275d9..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanOAuth2DeviceTokenStoreProviderFactory.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2019 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.commons.api.BasicCache;
-import org.keycloak.Config;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
-import org.keycloak.models.OAuth2DeviceTokenStoreProviderFactory;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-
-import java.util.function.Supplier;
-import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;
-
-/**
- * @author Hiroyuki Wada
- */
-public class InfinispanOAuth2DeviceTokenStoreProviderFactory implements OAuth2DeviceTokenStoreProviderFactory {
-
- // Reuse "actionTokens" infinispan cache for now
- private volatile Supplier> codeCache;
-
- @Override
- public OAuth2DeviceTokenStoreProvider create(KeycloakSession session) {
- lazyInit(session);
- return new InfinispanOAuth2DeviceTokenStoreProvider(session, codeCache);
- }
-
- private void lazyInit(KeycloakSession session) {
- if (codeCache == null) {
- synchronized (this) {
- codeCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
- }
- }
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public String getId() {
- return "infinispan";
- }
-
- @Override
- public int order() {
- return PROVIDER_PRIORITY;
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProvider.java
deleted file mode 100644
index 4a3e78781d9..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProvider.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.PushedAuthzRequestStoreProvider;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import org.keycloak.connections.infinispan.InfinispanUtil;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-
-public class InfinispanPushedAuthzRequestStoreProvider implements PushedAuthzRequestStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanPushedAuthzRequestStoreProvider.class);
-
- private final Supplier> parDataCache;
-
- public InfinispanPushedAuthzRequestStoreProvider(KeycloakSession session, Supplier> actionKeyCache) {
- this.parDataCache = actionKeyCache;
- }
-
- @Override
- public void put(UUID key, int lifespanSeconds, Map codeData) {
- ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(codeData);
-
- try {
- BasicCache cache = parDataCache.get();
- long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanSeconds));
- cache.put(key, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when adding PAR data for redirect URI: %s", key);
- }
-
- throw re;
- }
- }
-
- @Override
- public Map remove(UUID key) {
- try {
- BasicCache cache = parDataCache.get();
- ActionTokenValueEntity existing = cache.remove(key);
- return existing == null ? null : existing.getNotes();
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when removing PAR data for redirect URI %s", key);
- }
-
- return null;
- }
- }
-
-
- @Override
- public void close() {
-
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProviderFactory.java
deleted file mode 100644
index ce819607610..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanPushedAuthzRequestStoreProviderFactory.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.commons.api.BasicCache;
-import org.keycloak.Config;
-import org.keycloak.common.Profile;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.PushedAuthzRequestStoreProvider;
-import org.keycloak.models.PushedAuthzRequestStoreProviderFactory;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import org.keycloak.provider.EnvironmentDependentProviderFactory;
-
-import java.util.UUID;
-import java.util.function.Supplier;
-
-public class InfinispanPushedAuthzRequestStoreProviderFactory implements PushedAuthzRequestStoreProviderFactory, EnvironmentDependentProviderFactory {
-
- // Reuse "actionTokens" infinispan cache for now
- private volatile Supplier> codeCache;
-
- @Override
- public PushedAuthzRequestStoreProvider create(KeycloakSession session) {
- lazyInit(session);
- return new InfinispanPushedAuthzRequestStoreProvider(session, codeCache);
- }
-
- private void lazyInit(KeycloakSession session) {
- if (codeCache == null) {
- synchronized (this) {
- if (codeCache == null) {
- this.codeCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
- }
- }
- }
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public String getId() {
- return "infinispan";
- }
-
- @Override
- public boolean isSupported() {
- return Profile.isFeatureEnabled(Profile.Feature.PAR);
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProvider.java
deleted file mode 100644
index db4aeeeaa89..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProvider.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.AuthenticatedClientSessionModel;
-import org.keycloak.models.SamlArtifactSessionMappingModel;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
-import org.keycloak.connections.infinispan.InfinispanUtil;
-
-import java.nio.charset.StandardCharsets;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-
-/**
- * @author mhajas
- */
-public class InfinispanSamlArtifactSessionMappingStoreProvider implements SamlArtifactSessionMappingStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanSamlArtifactSessionMappingStoreProvider.class);
-
- private final Supplier> cacheSupplier;
-
- public InfinispanSamlArtifactSessionMappingStoreProvider(Supplier> actionKeyCache) {
- this.cacheSupplier = actionKeyCache;
- }
-
- @Override
- public void put(String artifact, int lifespanSeconds, AuthenticatedClientSessionModel clientSessionModel) {
- try {
- BasicCache cache = cacheSupplier.get();
- long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanSeconds));
- cache.put(UUID.nameUUIDFromBytes(artifact.getBytes(StandardCharsets.UTF_8)), new String[]{artifact, clientSessionModel.getUserSession().getId(), clientSessionModel.getClient().getId()}, lifespanMs, TimeUnit.MILLISECONDS);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed adding artifact %s", artifact);
- }
-
- throw re;
- }
- }
-
- @Override
- public SamlArtifactSessionMappingModel get(String artifact) {
- try {
- BasicCache cache = cacheSupplier.get();
- String[] existing = cache.get(UUID.nameUUIDFromBytes(artifact.getBytes(StandardCharsets.UTF_8)));
- if (existing == null || existing.length != 3) return null;
- if (!artifact.equals(existing[0])) return null; // Check
- return new SamlArtifactSessionMappingModel(existing[1], existing[2]);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when obtaining data for artifact %s", artifact);
- }
-
- return null;
- }
- }
-
- @Override
- public void remove(String artifact) {
- try {
- BasicCache cache = cacheSupplier.get();
- if (cache.remove(UUID.nameUUIDFromBytes(artifact.getBytes(StandardCharsets.UTF_8))) == null) {
- logger.debugf("Artifact %s was already removed", artifact);
- }
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed to remove artifact %s", artifact);
- }
- }
- }
-
- @Override
- public void close() {
-
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProviderFactory.java
deleted file mode 100644
index d802be4fbd0..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSamlArtifactSessionMappingStoreProviderFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.Config;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProviderFactory;
-
-import java.util.UUID;
-import java.util.function.Supplier;
-import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;
-
-/**
- * @author mhajas
- */
-public class InfinispanSamlArtifactSessionMappingStoreProviderFactory implements SamlArtifactSessionMappingStoreProviderFactory {
-
- private static final Logger LOG = Logger.getLogger(InfinispanSamlArtifactSessionMappingStoreProviderFactory.class);
-
- // Reuse "actionTokens" infinispan cache for now
- private volatile Supplier> codeCache;
-
- @Override
- public SamlArtifactSessionMappingStoreProvider create(KeycloakSession session) {
- lazyInit(session);
- return new InfinispanSamlArtifactSessionMappingStoreProvider(codeCache);
- }
-
- private void lazyInit(KeycloakSession session) {
- if (codeCache == null) {
- synchronized (this) {
- if (codeCache == null) {
- this.codeCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
- }
- }
- }
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public String getId() {
- return "infinispan";
- }
-
- @Override
- public int order() {
- return PROVIDER_PRIORITY;
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProvider.java
new file mode 100644
index 00000000000..61a84bf37db
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProvider.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.models.sessions.infinispan;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+import org.infinispan.client.hotrod.exceptions.HotRodClientException;
+import org.infinispan.commons.api.BasicCache;
+import org.jboss.logging.Logger;
+import org.keycloak.common.util.Time;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.SingleUseObjectProvider;
+import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
+import org.keycloak.connections.infinispan.InfinispanUtil;
+
+/**
+ * TODO: Check if Boolean can be used as single-use cache argument instead of ActionTokenValueEntity. With respect to other single-use cache usecases like "Revoke Refresh Token" .
+ * Also with respect to the usage of streams iterating over "actionTokens" cache (check there are no ClassCastExceptions when casting values directly to ActionTokenValueEntity)
+ *
+ *
+ * @author Marek Posolda
+ */
+public class InfinispanSingleUseObjectProvider implements SingleUseObjectProvider {
+
+ public static final Logger logger = Logger.getLogger(InfinispanSingleUseObjectProvider.class);
+
+ private final Supplier> tokenCache;
+ private final KeycloakSession session;
+
+ public InfinispanSingleUseObjectProvider(KeycloakSession session, Supplier> actionKeyCache) {
+ this.session = session;
+ this.tokenCache = actionKeyCache;
+ }
+
+ @Override
+ public void put(String key, long lifespanSeconds, Map notes) {
+ ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(notes);
+
+ try {
+ BasicCache cache = tokenCache.get();
+ long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanSeconds));
+ cache.put(key, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
+ } catch (HotRodClientException re) {
+ // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
+ if (logger.isDebugEnabled()) {
+ logger.debugf(re, "Failed when adding code %s", key);
+ }
+
+ throw re;
+ }
+ }
+
+ @Override
+ public Map get(String key) {
+ BasicCache cache = tokenCache.get();
+ ActionTokenValueEntity actionTokenValueEntity = cache.get(key);
+ return actionTokenValueEntity != null ? actionTokenValueEntity.getNotes() : null;
+ }
+
+ @Override
+ public Map remove(String key) {
+ try {
+ BasicCache cache = tokenCache.get();
+ ActionTokenValueEntity existing = cache.remove(key);
+ return existing == null ? null : existing.getNotes();
+ } catch (HotRodClientException re) {
+ // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
+ // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to remove the code from different place.
+ if (logger.isDebugEnabled()) {
+ logger.debugf(re, "Failed when removing code %s", key);
+ }
+
+ return null;
+ }
+ }
+
+ @Override
+ public boolean replace(String key, Map notes) {
+ BasicCache cache = tokenCache.get();
+ return cache.replace(key, new ActionTokenValueEntity(notes)) != null;
+ }
+
+ @Override
+ public boolean putIfAbsent(String key, long lifespanInSeconds) {
+ ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(null);
+
+ try {
+ BasicCache cache = tokenCache.get();
+ long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanInSeconds));
+ ActionTokenValueEntity existing = cache.putIfAbsent(key, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
+ return existing == null;
+ } catch (HotRodClientException re) {
+ // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
+ // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to use the token from different place.
+ logger.debugf(re, "Failed when adding token %s", key);
+
+ return false;
+ }
+
+ }
+
+ @Override
+ public boolean contains(String key) {
+ BasicCache cache = tokenCache.get();
+ return cache.containsKey(key);
+ }
+
+ @Override
+ public void close() {
+
+ }
+}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProviderFactory.java
similarity index 89%
rename from model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProviderFactory.java
rename to model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProviderFactory.java
index 5143e3206e8..0b60b8b614a 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseObjectProviderFactory.java
@@ -28,7 +28,7 @@ import org.keycloak.Config;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.SingleUseTokenStoreProviderFactory;
+import org.keycloak.models.SingleUseObjectProviderFactory;
import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
import org.keycloak.connections.infinispan.InfinispanUtil;
import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;
@@ -36,17 +36,17 @@ import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSe
/**
* @author Marek Posolda
*/
-public class InfinispanSingleUseTokenStoreProviderFactory implements SingleUseTokenStoreProviderFactory {
+public class InfinispanSingleUseObjectProviderFactory implements SingleUseObjectProviderFactory {
- private static final Logger LOG = Logger.getLogger(InfinispanSingleUseTokenStoreProviderFactory.class);
+ private static final Logger LOG = Logger.getLogger(InfinispanSingleUseObjectProviderFactory.class);
// Reuse "actionTokens" infinispan cache for now
private volatile Supplier> tokenCache;
@Override
- public InfinispanSingleUseTokenStoreProvider create(KeycloakSession session) {
+ public InfinispanSingleUseObjectProvider create(KeycloakSession session) {
lazyInit(session);
- return new InfinispanSingleUseTokenStoreProvider(session, tokenCache);
+ return new InfinispanSingleUseObjectProvider(session, tokenCache);
}
private void lazyInit(KeycloakSession session) {
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProvider.java
deleted file mode 100644
index cd9a0066272..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanSingleUseTokenStoreProvider.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.SingleUseTokenStoreProvider;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import org.keycloak.connections.infinispan.InfinispanUtil;
-
-/**
- * TODO: Check if Boolean can be used as single-use cache argument instead of ActionTokenValueEntity. With respect to other single-use cache usecases like "Revoke Refresh Token" .
- * Also with respect to the usage of streams iterating over "actionTokens" cache (check there are no ClassCastExceptions when casting values directly to ActionTokenValueEntity)
- *
- *
- * @author Marek Posolda
- */
-public class InfinispanSingleUseTokenStoreProvider implements SingleUseTokenStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanSingleUseTokenStoreProvider.class);
-
- private final Supplier> tokenCache;
- private final KeycloakSession session;
-
- public InfinispanSingleUseTokenStoreProvider(KeycloakSession session, Supplier> actionKeyCache) {
- this.session = session;
- this.tokenCache = actionKeyCache;
- }
-
- @Override
- public boolean putIfAbsent(String tokenId, int lifespanInSeconds) {
- ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(null);
-
- // Rather keep the items in the cache for a bit longer
- lifespanInSeconds = lifespanInSeconds + 10;
-
- try {
- BasicCache cache = tokenCache.get();
- long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanInSeconds));
- ActionTokenValueEntity existing = cache.putIfAbsent(tokenId, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
- return existing == null;
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- // In case of lock conflict, we don't want to retry anyway as there was likely an attempt to use the token from different place.
- logger.debugf(re, "Failed when adding token %s", tokenId);
-
- return false;
- }
-
- }
-
- @Override
- public void close() {
-
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProvider.java
deleted file mode 100644
index 3e9a6399c1a..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProvider.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-import org.infinispan.client.hotrod.exceptions.HotRodClientException;
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.TokenRevocationStoreProvider;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import org.keycloak.connections.infinispan.InfinispanUtil;
-
-/**
- * @author Marek Posolda
- */
-public class InfinispanTokenRevocationStoreProvider implements TokenRevocationStoreProvider {
-
- public static final Logger logger = Logger.getLogger(InfinispanTokenRevocationStoreProvider.class);
-
- private final Supplier> tokenCache;
- private final KeycloakSession session;
-
- // Key in the data, which indicates that token is considered revoked
- private final String REVOKED_KEY = "revoked";
-
- public InfinispanTokenRevocationStoreProvider(KeycloakSession session, Supplier> tokenCache) {
- this.session = session;
- this.tokenCache = tokenCache;
- }
-
-
- @Override
- public void putRevokedToken(String tokenId, long lifespanSeconds) {
- Map data = Collections.singletonMap(REVOKED_KEY, "true");
- ActionTokenValueEntity tokenValue = new ActionTokenValueEntity(data);
-
- try {
- BasicCache cache = tokenCache.get();
- long lifespanMs = InfinispanUtil.toHotrodTimeMs(cache, Time.toMillis(lifespanSeconds + 1));
- cache.put(tokenId, tokenValue, lifespanMs, TimeUnit.MILLISECONDS);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when adding revoked token %s", tokenId);
- }
-
- throw re;
- }
- }
-
-
- @Override
- public boolean isRevoked(String tokenId) {
- try {
- BasicCache cache = tokenCache.get();
- ActionTokenValueEntity existing = cache.get(tokenId);
-
- if (existing == null) {
- return false;
- }
-
- return existing.getNotes().containsKey(REVOKED_KEY);
- } catch (HotRodClientException re) {
- // No need to retry. The hotrod (remoteCache) has some retries in itself in case of some random network error happened.
- if (logger.isDebugEnabled()) {
- logger.debugf(re, "Failed when trying to get revoked token %s", tokenId);
- }
-
- return false;
- }
- }
-
- @Override
- public void close() {
-
- }
-}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProviderFactory.java
deleted file mode 100644
index 6e9c8308ab6..00000000000
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanTokenRevocationStoreProviderFactory.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2020 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.keycloak.models.sessions.infinispan;
-
-import java.util.function.Supplier;
-
-import org.infinispan.commons.api.BasicCache;
-import org.jboss.logging.Logger;
-import org.keycloak.Config;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.TokenRevocationStoreProvider;
-import org.keycloak.models.TokenRevocationStoreProviderFactory;
-import org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity;
-import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;
-
-/**
- * @author Marek Posolda
- */
-public class InfinispanTokenRevocationStoreProviderFactory implements TokenRevocationStoreProviderFactory {
-
- // Reuse "actionTokens" infinispan cache for now
- private volatile Supplier> tokenCache;
-
- @Override
- public TokenRevocationStoreProvider create(KeycloakSession session) {
- lazyInit(session);
- return new InfinispanTokenRevocationStoreProvider(session, tokenCache);
- }
-
- private void lazyInit(KeycloakSession session) {
- if (tokenCache == null) {
- synchronized (this) {
- if (tokenCache == null) {
- this.tokenCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
- }
- }
- }
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public String getId() {
- return "infinispan";
- }
-
- @Override
- public int order() {
- return PROVIDER_PRIORITY;
- }
-}
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.OAuth2DeviceTokenStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.OAuth2DeviceTokenStoreProviderFactory
deleted file mode 100644
index 4c77370f6b4..00000000000
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.OAuth2DeviceTokenStoreProviderFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright 2019 Red Hat, Inc. and/or its affiliates
-# and other contributors as indicated by the @author tags.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.keycloak.models.sessions.infinispan.InfinispanOAuth2DeviceTokenStoreProviderFactory
\ No newline at end of file
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.PushedAuthzRequestStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.PushedAuthzRequestStoreProviderFactory
deleted file mode 100644
index 131bf6dd8b6..00000000000
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.PushedAuthzRequestStoreProviderFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright 2021 Red Hat, Inc. and/or its affiliates
-# and other contributors as indicated by the @author tags.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.keycloak.models.sessions.infinispan.InfinispanPushedAuthzRequestStoreProviderFactory
\ No newline at end of file
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SamlArtifactSessionMappingStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SamlArtifactSessionMappingStoreProviderFactory
deleted file mode 100644
index c615b1f1fe4..00000000000
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SamlArtifactSessionMappingStoreProviderFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright 2021 Red Hat, Inc. and/or its affiliates
-# and other contributors as indicated by the @author tags.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.keycloak.models.sessions.infinispan.InfinispanSamlArtifactSessionMappingStoreProviderFactory
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.CodeToTokenStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseObjectProviderFactory
similarity index 89%
rename from model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.CodeToTokenStoreProviderFactory
rename to model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseObjectProviderFactory
index e42a1ad1d6a..af73aedf8cb 100644
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.CodeToTokenStoreProviderFactory
+++ b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseObjectProviderFactory
@@ -15,4 +15,4 @@
# limitations under the License.
#
-org.keycloak.models.sessions.infinispan.InfinispanCodeToTokenStoreProviderFactory
\ No newline at end of file
+org.keycloak.models.sessions.infinispan.InfinispanSingleUseObjectProviderFactory
\ No newline at end of file
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseTokenStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseTokenStoreProviderFactory
deleted file mode 100644
index 56134b0e81a..00000000000
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.SingleUseTokenStoreProviderFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright 2017 Red Hat, Inc. and/or its affiliates
-# and other contributors as indicated by the @author tags.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.keycloak.models.sessions.infinispan.InfinispanSingleUseTokenStoreProviderFactory
\ No newline at end of file
diff --git a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.TokenRevocationStoreProviderFactory b/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.TokenRevocationStoreProviderFactory
deleted file mode 100644
index 140d4ffd517..00000000000
--- a/model/infinispan/src/main/resources/META-INF/services/org.keycloak.models.TokenRevocationStoreProviderFactory
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright 2020 Red Hat, Inc. and/or its affiliates
-# and other contributors as indicated by the @author tags.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-
-org.keycloak.models.sessions.infinispan.InfinispanTokenRevocationStoreProviderFactory
\ No newline at end of file
diff --git a/server-spi-private/src/main/java/org/keycloak/models/ActionTokenStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/ActionTokenStoreProvider.java
index 9061c96174b..d71aa90870b 100644
--- a/server-spi-private/src/main/java/org/keycloak/models/ActionTokenStoreProvider.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/ActionTokenStoreProvider.java
@@ -23,7 +23,7 @@ import java.util.Map;
/**
* Internal action token store provider.
*
- * It's used for store the details about used action tokens. There is separate provider for OAuth2 codes - {@link CodeToTokenStoreProvider},
+ * It's used for store the details about used action tokens. There is separate provider for OAuth2 codes - {@link SingleUseObjectProvider},
* which may reuse some components (eg. same infinispan cache)
*
* @author hmlnarik
diff --git a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProvider.java
deleted file mode 100644
index a6ffa2fcf65..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProvider.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import java.util.Map;
-import java.util.UUID;
-
-import org.keycloak.provider.Provider;
-
-/**
- * Provides single-use cache for OAuth2 code parameter. Used to ensure that particular value of code parameter is used once.
- *
- * For now, it is separate provider as it's a bit different use-case than {@link ActionTokenStoreProvider}, however it may reuse some components (eg. same infinispan cache)
- *
- * @author Marek Posolda
- */
-public interface CodeToTokenStoreProvider extends Provider {
-
- /**
- * Stores the given data and guarantees that data should be available in the store for at least the time specified by {@param lifespanSeconds} parameter
- * @param codeId
- * @param lifespanSeconds
- * @param codeData
- * @return true if data were successfully put
- */
- void put(UUID codeId, int lifespanSeconds, Map codeData);
-
-
- /**
- * This method returns data just if removal was successful. Implementation should guarantee that "remove" is single-use. So if
- * 2 threads (even on different cluster nodes or on different cross-dc nodes) calls "remove(123)" concurrently, then just one of them
- * is allowed to succeed and return data back. It can't happen that both will succeed.
- *
- * @param codeId
- * @return context data related to OAuth2 code. It returns null if there are not context data available.
- */
- Map remove(UUID codeId);
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProvider.java
deleted file mode 100755
index fb566881a93..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProvider.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2019 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-
-import java.util.Map;
-
-
-/**
- * Provides cache for OAuth2 Device Authorization Grant tokens.
- *
- * @author Hiroyuki Wada
- */
-public interface OAuth2DeviceTokenStoreProvider extends Provider {
-
- /**
- * Stores the given device code and user code
- *
- * @param deviceCode
- * @param userCode
- * @param lifespanSeconds
- */
- void put(OAuth2DeviceCodeModel deviceCode, OAuth2DeviceUserCodeModel userCode, int lifespanSeconds);
-
- /**
- * Get the model object by the given device code
- *
- * @param realm
- * @param deviceCode
- * @return
- */
- OAuth2DeviceCodeModel getByDeviceCode(RealmModel realm, String deviceCode);
-
- /**
- * Check the device code is allowed to poll
- *
- * @param deviceCode
- * @return Return true if the given device code is allowed to poll
- */
- boolean isPollingAllowed(OAuth2DeviceCodeModel deviceCode);
-
- /**
- * Get the model object by the given user code
- *
- * @param realm
- * @param userCode
- * @return
- */
- OAuth2DeviceCodeModel getByUserCode(RealmModel realm, String userCode);
-
- /**
- * Approve the given user code
- *
- * @param realm
- * @param userCode
- * @param userSessionId
- * @return Return true if approving successful. If the code is already expired and cleared, it returns false.
- */
- boolean approve(RealmModel realm, String userCode, String userSessionId, Map additionalParams);
-
- /**
- * Deny the given user code
- *
- * @param realm
- * @param userCode
- * @return Return true if denying successful. If the code is already expired and cleared, it returns false.
- */
- boolean deny(RealmModel realm, String userCode);
-
- /**
- * Remove the given device code
- *
- * @param realm
- * @param deviceCode
- * @return Return true if removing successful. If the code is already expired and cleared, it returns false.
- */
- boolean removeDeviceCode(RealmModel realm, String deviceCode);
-
- /**
- * Remove the given user code
- *
- * @param realm
- * @param userCode
- * @return Return true if removing successful. If the code is already expired and cleared, it returns false.
- */
- boolean removeUserCode(RealmModel realm, String userCode);
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProviderFactory.java
deleted file mode 100644
index 076dc9e6143..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreProviderFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2019 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.ProviderFactory;
-
-/**
- * @author Hiroyuki Wada
- */
-public interface OAuth2DeviceTokenStoreProviderFactory extends ProviderFactory {
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreSpi.java
deleted file mode 100644
index 699076760c9..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/OAuth2DeviceTokenStoreSpi.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2019 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.provider.Spi;
-
-/**
- * @author Hiroyuki Wada
- */
-public class OAuth2DeviceTokenStoreSpi implements Spi {
-
- public static final String NAME = "oauth2DeviceTokenStore";
-
- @Override
- public boolean isInternal() {
- return true;
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Class extends Provider> getProviderClass() {
- return OAuth2DeviceTokenStoreProvider.class;
- }
-
- @Override
- public Class extends ProviderFactory> getProviderFactoryClass() {
- return OAuth2DeviceTokenStoreProviderFactory.class;
- }
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProvider.java
deleted file mode 100644
index 9bb8069dc39..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * Provides single-use cache for Pushed Authorization Request. The data of this request may be used only once.
- */
-public interface PushedAuthzRequestStoreProvider extends Provider {
-
- /**
- * Stores the given data and guarantees that data should be available in the store for at least the time specified by {@param lifespanSeconds} parameter.
- *
- * @param key unique identifier
- * @param lifespanSeconds time to live
- * @param codeData the data to store
- */
- void put(UUID key, int lifespanSeconds, Map codeData);
-
-
- /**
- * This method returns data just if removal was successful. Implementation should guarantee that "remove" is single-use. So if
- * 2 threads (even on different cluster nodes or on different cross-dc nodes) calls "remove(123)" concurrently, then just one of them
- * is allowed to succeed and return data back. It can't happen that both will succeed.
- *
- * @param key unique identifier
- * @return context data related Pushed Authorization Request. It returns null if there is no context data available.
- */
- Map remove(UUID key);
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProviderFactory.java
deleted file mode 100644
index f6c38794c79..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreProviderFactory.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.ProviderFactory;
-
-public interface PushedAuthzRequestStoreProviderFactory extends ProviderFactory {
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreSpi.java
deleted file mode 100644
index 5471a0fad59..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/PushedAuthzRequestStoreSpi.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.provider.Spi;
-
-public class PushedAuthzRequestStoreSpi implements Spi {
-
- public static final String NAME = "pushedAuthzRequestStore";
-
- @Override
- public boolean isInternal() {
- return true;
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Class extends Provider> getProviderClass() {
- return PushedAuthzRequestStoreProvider.class;
- }
-
- @Override
- public Class extends ProviderFactory> getProviderFactoryClass() {
- return PushedAuthzRequestStoreProviderFactory.class;
- }
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProvider.java
deleted file mode 100644
index 451652048eb..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProvider.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-
-/**
- * Provides cache for session mapping for SAML artifacts.
- *
- * For now, it is separate provider as it's a bit different use-case than {@link ActionTokenStoreProvider}, however it may reuse some components (eg. same infinispan cache)
- *
- * @author mhajas
- */
-public interface SamlArtifactSessionMappingStoreProvider extends Provider {
-
- /**
- * Stores the given data and guarantees that data should be available in the store for at least the time specified by {@param lifespanSeconds} parameter
- *
- * @param artifact
- * @param lifespanSeconds
- * @param clientSessionModel
- */
- void put(String artifact, int lifespanSeconds, AuthenticatedClientSessionModel clientSessionModel);
-
-
- /**
- * This method returns session mapping associated with the given {@param artifact}
- *
- * @param artifact
- * @return session mapping corresponding to given artifact or {@code null} if it does not exist.
- */
- SamlArtifactSessionMappingModel get(String artifact);
-
- /**
- * Removes data for the given {@param artifact} from the store
- *
- * @param artifact
- */
- void remove(String artifact);
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProviderFactory.java
deleted file mode 100644
index c8d003d23cd..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreProviderFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.ProviderFactory;
-
-/**
- * @author mhajas
- */
-public interface SamlArtifactSessionMappingStoreProviderFactory extends ProviderFactory {
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreSpi.java
deleted file mode 100644
index 73115679980..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SamlArtifactSessionMappingStoreSpi.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.provider.Spi;
-
-/**
- * @author mhajas
- */
-public class SamlArtifactSessionMappingStoreSpi implements Spi {
-
- public static final String NAME = "samlArtifactSessionMappingStore";
-
- @Override
- public boolean isInternal() {
- return true;
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Class extends Provider> getProviderClass() {
- return SamlArtifactSessionMappingStoreProvider.class;
- }
-
- @Override
- public Class extends ProviderFactory> getProviderFactoryClass() {
- return SamlArtifactSessionMappingStoreProviderFactory.class;
- }
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProvider.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProvider.java
new file mode 100644
index 00000000000..08a65245d04
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProvider.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.models;
+
+import org.keycloak.provider.Provider;
+
+import java.util.Map;
+
+/**
+ * Provides a cache to store data for single-use use case. Data are represented by a {@code String} key.
+ *
+ * @author Marek Posolda
+ */
+public interface SingleUseObjectProvider extends Provider {
+
+ // suffix to a key to indicate that token is considered revoked
+ String REVOKED_KEY = ".revoked";
+
+ /**
+ * Stores the given data and guarantees that data should be available in the store for at least the time specified by {@param lifespanSeconds} parameter
+ * @param key
+ * @param lifespanSeconds
+ * @param notes
+ */
+ void put(String key, long lifespanSeconds, Map notes);
+
+ /**
+ * Gets data associated with the given key.
+ * @param key String
+ * @return Map Data associated with the given key or {@code null} if there is no associated data.
+ */
+ Map get(String key);
+
+ /**
+ * This method returns data just if removal was successful. Implementation should guarantee that "remove" is single-use. So if
+ * 2 threads (even on different cluster nodes or on different cross-dc nodes) calls "remove(123)" concurrently, then just one of them
+ * is allowed to succeed and return data back. It can't happen that both will succeed.
+ *
+ * @param key
+ * @return context data associated to the key. It returns {@code null} if there are no context data available.
+ */
+ Map remove(String key);
+
+ /**
+ * Replaces data associated with the given key in the store if the store contains the key.
+ * @param key String
+ * @param notes Map New data to be stored
+ * @return {@code true} if the store contains the key and data was replaced, otherwise {@code false}.
+ */
+ boolean replace(String key, Map notes);
+
+ /**
+ * Will try to put the key into the cache. It will succeed just if key is not already there.
+ *
+ * @param key
+ * @param lifespanInSeconds Minimum lifespan for which successfully added key will be kept in the cache.
+ * @return true if the key was successfully put into the cache. This means that same key wasn't in the cache before
+ */
+ boolean putIfAbsent(String key, long lifespanInSeconds);
+
+ /**
+ * Checks if there is a record in the store for the given key.
+ * @param key String
+ * @return {@code true} if the record is present in the store, {@code false} otherwise.
+ */
+ boolean contains(String key);
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProviderFactory.java
similarity index 89%
rename from server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProviderFactory.java
rename to server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProviderFactory.java
index 85b240100d1..974b5e23726 100644
--- a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreProviderFactory.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectProviderFactory.java
@@ -22,5 +22,5 @@ import org.keycloak.provider.ProviderFactory;
/**
* @author Marek Posolda
*/
-public interface CodeToTokenStoreProviderFactory extends ProviderFactory {
+public interface SingleUseObjectProviderFactory extends ProviderFactory {
}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectSpi.java
similarity index 85%
rename from server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreSpi.java
rename to server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectSpi.java
index e71ade63034..b52efcfaf2d 100644
--- a/server-spi-private/src/main/java/org/keycloak/models/CodeToTokenStoreSpi.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/SingleUseObjectSpi.java
@@ -24,9 +24,9 @@ import org.keycloak.provider.Spi;
/**
* @author Marek Posolda
*/
-public class CodeToTokenStoreSpi implements Spi {
+public class SingleUseObjectSpi implements Spi {
- public static final String NAME = "codeToTokenStore";
+ public static final String NAME = "singleUseObject";
@Override
public boolean isInternal() {
@@ -40,11 +40,11 @@ public class CodeToTokenStoreSpi implements Spi {
@Override
public Class extends Provider> getProviderClass() {
- return CodeToTokenStoreProvider.class;
+ return SingleUseObjectProvider.class;
}
@Override
public Class extends ProviderFactory> getProviderFactoryClass() {
- return CodeToTokenStoreProviderFactory.class;
+ return SingleUseObjectProviderFactory.class;
}
}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProvider.java
deleted file mode 100644
index 349b21dde5c..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProvider.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-
-/**
- * Provides single-use cache for OAuth2 code parameter. Used to ensure that particular value of code parameter is used once.
- *
- * TODO: For now, it is separate provider as {@link CodeToTokenStoreProvider}, however will be good to merge those 2 providers to "SingleUseCacheProvider"
- * in the future as they provide very similar thing
- *
- * @author Marek Posolda
- */
-public interface SingleUseTokenStoreProvider extends Provider {
-
- /**
- * Will try to put the token into the cache. It will success just if token is not already there.
- *
- * @param tokenId
- * @param lifespanInSeconds Minimum lifespan for which successfully added token will be kept in the cache.
- * @return true if token was successfully put into the cache. This means that same token wasn't in the cache before
- */
- boolean putIfAbsent(String tokenId, int lifespanInSeconds);
-
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProviderFactory.java
deleted file mode 100644
index 84f8fb12797..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreProviderFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.ProviderFactory;
-
-/**
- * @author Marek Posolda
- */
-public interface SingleUseTokenStoreProviderFactory extends ProviderFactory {
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreSpi.java
deleted file mode 100644
index f63a760088e..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/SingleUseTokenStoreSpi.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.provider.Spi;
-
-/**
- * @author Marek Posolda
- */
-public class SingleUseTokenStoreSpi implements Spi {
-
- public static final String NAME = "singleUseTokenStore";
-
- @Override
- public boolean isInternal() {
- return true;
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Class extends Provider> getProviderClass() {
- return SingleUseTokenStoreProvider.class;
- }
-
- @Override
- public Class extends ProviderFactory> getProviderFactoryClass() {
- return SingleUseTokenStoreProviderFactory.class;
- }
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProvider.java b/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProvider.java
deleted file mode 100644
index 73765b24569..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2020 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.keycloak.models;
-
-import java.util.UUID;
-
-import org.keycloak.provider.Provider;
-
-/**
- * Provides the cache for store revoked tokens.
- *
- * For now, it is separate provider as it is bit different use-case that existing providers like {@link CodeToTokenStoreProvider},
- * {@link SingleUseTokenStoreProvider} and {@link ActionTokenStoreProvider}
- *
- * @author Marek Posolda
- */
-public interface TokenRevocationStoreProvider extends Provider {
-
- /**
- * Mark given token as revoked. Parameter "lifespanSeconds" is the time for which the token is considered revoked. After this time, it may be removed from this store,
- * which means that {@link #isRevoked} method will return false. In reality, the token will usually still be invalid due the "expiration" claim on it, however
- * that is out of scope of this provider.
- *
- * @param tokenId
- * @oaran lifespanSeconds
- */
- void putRevokedToken(String tokenId, long lifespanSeconds);
-
- /**
- * @param tokenId
- * @return true if token exists in the store, which indicates that it is revoked.
- */
- boolean isRevoked(String tokenId);
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProviderFactory.java
deleted file mode 100644
index 4f3d78fa677..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreProviderFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2020 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.keycloak.models;
-import org.keycloak.provider.ProviderFactory;
-
-/**
- * @author Marek Posolda
- */
-public interface TokenRevocationStoreProviderFactory extends ProviderFactory {
-}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreSpi.java b/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreSpi.java
deleted file mode 100644
index 1a458ab1793..00000000000
--- a/server-spi-private/src/main/java/org/keycloak/models/TokenRevocationStoreSpi.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2020 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.keycloak.models;
-
-import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.provider.Spi;
-
-/**
- * @author Marek Posolda
- */
-public class TokenRevocationStoreSpi implements Spi {
-
- public static final String NAME = "tokenRevocationStore";
-
- @Override
- public boolean isInternal() {
- return true;
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public Class extends Provider> getProviderClass() {
- return TokenRevocationStoreProvider.class;
- }
-
- @Override
- public Class extends ProviderFactory> getProviderFactoryClass() {
- return TokenRevocationStoreProviderFactory.class;
- }
-
-}
diff --git a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index eb7c5d8311b..597c19c74ca 100755
--- a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -26,13 +26,8 @@ org.keycloak.models.RealmSpi
org.keycloak.models.RoleSpi
org.keycloak.models.DeploymentStateSpi
org.keycloak.models.ActionTokenStoreSpi
-org.keycloak.models.CodeToTokenStoreSpi
-org.keycloak.models.OAuth2DeviceTokenStoreSpi
org.keycloak.models.OAuth2DeviceUserCodeSpi
-org.keycloak.models.SamlArtifactSessionMappingStoreSpi
-org.keycloak.models.PushedAuthzRequestStoreSpi
-org.keycloak.models.SingleUseTokenStoreSpi
-org.keycloak.models.TokenRevocationStoreSpi
+org.keycloak.models.SingleUseObjectSpi
org.keycloak.models.UserSessionSpi
org.keycloak.models.UserLoginFailureSpi
org.keycloak.models.UserSpi
diff --git a/server-spi/src/main/java/org/keycloak/models/SamlArtifactSessionMappingModel.java b/server-spi/src/main/java/org/keycloak/models/SamlArtifactSessionMappingModel.java
deleted file mode 100644
index 2c24779280e..00000000000
--- a/server-spi/src/main/java/org/keycloak/models/SamlArtifactSessionMappingModel.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.keycloak.models;
-
-public class SamlArtifactSessionMappingModel {
-
- private final String userSessionId;
- private final String clientSessionId;
-
- public SamlArtifactSessionMappingModel(String userSessionId, String clientSessionId) {
- this.userSessionId = userSessionId;
- this.clientSessionId = clientSessionId;
- }
-
- public String getUserSessionId() {
- return userSessionId;
- }
-
- public String getClientSessionId() {
- return clientSessionId;
- }
-}
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
index ebf1ebc6dc3..f91781ac96e 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
@@ -29,7 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
@@ -44,7 +43,7 @@ import org.keycloak.keys.loader.PublicKeyStorageManager;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.SingleUseTokenStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
@@ -190,7 +189,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
throw new RuntimeException("Missing ID on the token");
}
- SingleUseTokenStoreProvider singleUseCache = context.getSession().getProvider(SingleUseTokenStoreProvider.class);
+ SingleUseObjectProvider singleUseCache = context.getSession().getProvider(SingleUseObjectProvider.class);
int lifespanInSecs = Math.max(token.getExpiration() - currentTime, 10);
if (singleUseCache.putIfAbsent(token.getId(), lifespanInSecs)) {
logger.tracef("Added token '%s' to single-use cache. Lifespan: %d seconds, client: %s", token.getId(), lifespanInSecs, clientId);
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java
index 7126294d568..31a04f233de 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientSecretAuthenticator.java
@@ -25,11 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import org.apache.http.client.utils.CloneUtils;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.AuthenticationFlowError;
@@ -37,9 +35,7 @@ import org.keycloak.authentication.ClientAuthenticationFlowContext;
import org.keycloak.common.util.Time;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.models.AuthenticationExecutionModel.Requirement;
-import org.keycloak.models.SingleUseTokenStoreProvider;
-import org.keycloak.models.delegate.ClientModelLazyDelegate;
-import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
import org.keycloak.protocol.oidc.OIDCClientSecretConfigWrapper;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -196,7 +192,7 @@ public class JWTClientSecretAuthenticator extends AbstractClientAuthenticator {
throw new RuntimeException("Missing ID on the token");
}
- SingleUseTokenStoreProvider singleUseCache = context.getSession().getProvider(SingleUseTokenStoreProvider.class);
+ SingleUseObjectProvider singleUseCache = context.getSession().getProvider(SingleUseObjectProvider.class);
int lifespanInSecs = Math.max(token.getExpiration() - currentTime, 10);
if (singleUseCache.putIfAbsent(token.getId(), lifespanInSecs)) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 5446a29ad25..00553dc97ff 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -231,7 +231,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
// Standard or hybrid flow
String code = null;
if (responseType.hasResponseType(OIDCResponseType.CODE)) {
- OAuth2Code codeData = new OAuth2Code(UUID.randomUUID(),
+ OAuth2Code codeData = new OAuth2Code(UUID.randomUUID().toString(),
Time.currentTime() + userSession.getRealm().getAccessCodeLifespan(),
nonce,
authSession.getClientNote(OAuth2Constants.SCOPE),
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 9a0fe0cf22a..0ff5570658d 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -25,7 +25,6 @@ import org.keycloak.OAuthErrorException;
import org.keycloak.TokenCategory;
import org.keycloak.TokenVerifier;
import org.keycloak.authentication.authenticators.util.AcrStore;
-import org.keycloak.authentication.authenticators.util.LoAUtil;
import org.keycloak.broker.oidc.OIDCIdentityProvider;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.cluster.ClusterProvider;
@@ -50,7 +49,7 @@ import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
-import org.keycloak.models.TokenRevocationStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
@@ -64,7 +63,6 @@ import org.keycloak.protocol.oidc.mappers.UserInfoTokenMapper;
import org.keycloak.rar.AuthorizationDetails;
import org.keycloak.representations.AuthorizationDetailsJSONRepresentation;
import org.keycloak.rar.AuthorizationRequestContext;
-import org.keycloak.protocol.oidc.utils.AcrUtils;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
@@ -1354,8 +1352,8 @@ public class TokenManager {
@Override
public boolean test(AccessToken token) {
- TokenRevocationStoreProvider revocationStore = session.getProvider(TokenRevocationStoreProvider.class);
- return !revocationStore.isRevoked(token.getId());
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ return !singleUseStore.contains(token.getId() + SingleUseObjectProvider.REVOKED_KEY);
}
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java
index 26b6e3c0588..42138445839 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java
@@ -17,6 +17,7 @@
package org.keycloak.protocol.oidc.endpoints;
+import java.util.Collections;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -41,7 +42,7 @@ import org.keycloak.headers.SecurityHeadersProvider;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.TokenRevocationStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.TokenManager;
@@ -257,9 +258,9 @@ public class TokenRevocationEndpoint {
}
private void revokeAccessToken() {
- TokenRevocationStoreProvider revocationStore = session.getProvider(TokenRevocationStoreProvider.class);
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
int currentTime = Time.currentTime();
long lifespanInSecs = Math.max(token.getExp() - currentTime, 10);
- revocationStore.putRevokedToken(token.getId(), lifespanInSecs);
+ singleUseStore.put(token.getId() + SingleUseObjectProvider.REVOKED_KEY, lifespanInSecs, Collections.emptyMap());
}
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/CibaGrantType.java b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/CibaGrantType.java
index 3fbfb9fc058..6a90a8c26d7 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/CibaGrantType.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/CibaGrantType.java
@@ -36,7 +36,6 @@ import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel;
@@ -49,6 +48,7 @@ import org.keycloak.protocol.oidc.grants.ciba.clientpolicy.context.BackchannelTo
import org.keycloak.protocol.oidc.grants.ciba.endpoints.CibaRootEndpoint;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.protocol.oidc.endpoints.TokenEndpoint;
+import org.keycloak.protocol.oidc.grants.device.DeviceGrantType;
import org.keycloak.services.CorsErrorResponseException;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.Urls;
@@ -160,8 +160,7 @@ public class CibaGrantType {
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
}
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- OAuth2DeviceCodeModel deviceCode = store.getByDeviceCode(realm, request.getId());
+ OAuth2DeviceCodeModel deviceCode = DeviceGrantType.getDeviceByDeviceCode(session, realm, request.getId());
if (deviceCode == null) {
// Auth Req ID has not put onto cache, no need to remove Auth Req ID.
@@ -179,8 +178,8 @@ public class CibaGrantType {
throw new CorsErrorResponseException(cors, OAuthErrorException.EXPIRED_TOKEN, "authentication timed out", Response.Status.BAD_REQUEST);
}
- if (!store.isPollingAllowed(deviceCode)) {
- logDebug("pooling.", request);
+ if (!DeviceGrantType.isPollingAllowed(session, deviceCode)) {
+ logDebug("polling.", request);
throw new CorsErrorResponseException(cors, OAuthErrorException.SLOW_DOWN, "too early to access", Response.Status.BAD_REQUEST);
}
@@ -198,7 +197,7 @@ public class CibaGrantType {
UserSessionModel userSession = createUserSession(request, deviceCode.getAdditionalParams());
UserModel user = userSession.getUser();
- store.removeDeviceCode(realm, request.getId());
+ DeviceGrantType.removeDeviceByDeviceCode(session, request. getId());
// Compute client scopes again from scope parameter. Check if user still has them granted
// (but in code-to-token request, it could just theoretically happen that they are not available)
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationCallbackEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationCallbackEndpoint.java
index e553b7a6b45..93d0a4101f8 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationCallbackEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationCallbackEndpoint.java
@@ -29,9 +29,10 @@ import org.keycloak.models.CibaConfig;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
import org.keycloak.protocol.oidc.grants.ciba.channel.AuthenticationChannelResponse;
import org.keycloak.protocol.oidc.grants.ciba.channel.AuthenticationChannelResponse.Status;
+import org.keycloak.protocol.oidc.grants.device.DeviceGrantType;
+import org.keycloak.protocol.oidc.grants.device.endpoints.DeviceEndpoint;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.Urls;
@@ -123,8 +124,7 @@ public class BackchannelAuthenticationCallbackEndpoint extends AbstractCibaEndpo
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.FORBIDDEN);
}
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- OAuth2DeviceCodeModel deviceCode = store.getByUserCode(realm, bearerToken.getId());
+ OAuth2DeviceCodeModel deviceCode = DeviceEndpoint.getDeviceByUserCode(session, realm, bearerToken.getId());
if (deviceCode == null) {
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.FORBIDDEN);
@@ -154,15 +154,13 @@ public class BackchannelAuthenticationCallbackEndpoint extends AbstractCibaEndpo
}
private void cancelRequest(String authResultId) {
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- OAuth2DeviceCodeModel userCode = store.getByUserCode(realm, authResultId);
- store.removeDeviceCode(realm, userCode.getDeviceCode());
- store.removeUserCode(realm, authResultId);
+ OAuth2DeviceCodeModel userCode = DeviceEndpoint.getDeviceByUserCode(session, realm, authResultId);
+ DeviceGrantType.removeDeviceByDeviceCode(session, userCode.getDeviceCode());
+ DeviceGrantType.removeDeviceByUserCode(session, realm, authResultId);
}
private void approveRequest(AccessToken authReqId, Map additionalParams) {
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- store.approve(realm, authReqId.getId(), "fake", additionalParams);
+ DeviceGrantType.approveUserCode(session, realm, authReqId.getId(), "fake", additionalParams);
}
private void denyRequest(AccessToken authReqId, Status status) {
@@ -172,9 +170,7 @@ public class BackchannelAuthenticationCallbackEndpoint extends AbstractCibaEndpo
event.error(Errors.CONSENT_DENIED);
}
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
-
- store.deny(realm, authReqId.getId());
+ DeviceGrantType.denyUserCode(session, realm, authReqId.getId());
}
protected void sendClientNotificationRequest(ClientModel client, CibaConfig cibaConfig, OAuth2DeviceCodeModel deviceModel) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationEndpoint.java
index 9ffdf373c9e..6cfeb6e0ce2 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/grants/ciba/endpoints/BackchannelAuthenticationEndpoint.java
@@ -27,9 +27,9 @@ import org.keycloak.models.CibaConfig;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
import org.keycloak.models.OAuth2DeviceUserCodeModel;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserModel;
import org.keycloak.protocol.oidc.grants.ciba.CibaGrantType;
import org.keycloak.protocol.oidc.grants.ciba.channel.AuthenticationChannelProvider;
@@ -123,7 +123,7 @@ public class BackchannelAuthenticationEndpoint extends AbstractCibaEndpoint {
/**
* TODO: Leverage the device code storage for tracking authentication requests. Not sure if we need a specific storage,
- * but probably make the {@link OAuth2DeviceTokenStoreProvider} more generic for ciba, device, or any other use case
+ * or we can leverage the {@link SingleUseObjectProvider} for ciba, device, or any other use case
* that relies on cross-references for unsolicited user authentication requests from devices.
*/
private void storeAuthenticationRequest(CIBAAuthenticationRequest request, CibaConfig cibaConfig, String authReqId) {
@@ -147,9 +147,10 @@ public class BackchannelAuthenticationEndpoint extends AbstractCibaEndpoint {
// To inform "expired_token" to the client, the lifespan of the cache provider is longer than device code
int lifespanSeconds = expiresIn + poolingInterval + 10;
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
- store.put(deviceCode, userCode, lifespanSeconds);
+ singleUseStore.put(deviceCode.serializeKey(), lifespanSeconds, deviceCode.toMap());
+ singleUseStore.put(userCode.serializeKey(), lifespanSeconds, userCode.serializeValue());
}
private CIBAAuthenticationRequest authorizeClient(MultivaluedMap params) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/grants/device/DeviceGrantType.java b/services/src/main/java/org/keycloak/protocol/oidc/grants/device/DeviceGrantType.java
index aa2f9ef05bd..04a700678a0 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/grants/device/DeviceGrantType.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/grants/device/DeviceGrantType.java
@@ -26,14 +26,14 @@ import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakUriInfo;
import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
+import org.keycloak.models.OAuth2DeviceUserCodeModel;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.LoginProtocol;
@@ -60,7 +60,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
-import java.util.stream.Stream;
+import java.util.Map;
/**
* @author Hiroyuki Wada
@@ -101,8 +101,7 @@ public class DeviceGrantType {
String errorType = OAuthErrorException.SERVER_ERROR;
if (error == LoginProtocol.Error.CONSENT_DENIED) {
String verifiedUserCode = authSession.getClientNote(DeviceGrantType.OAUTH2_DEVICE_VERIFIED_USER_CODE);
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- if (!store.deny(realm, verifiedUserCode)) {
+ if (!denyUserCode(session, realm, verifiedUserCode)) {
// Already expired and removed in the store
errorType = OAuthErrorException.EXPIRED_TOKEN;
} else {
@@ -123,8 +122,7 @@ public class DeviceGrantType {
String verifiedUserCode = authSession.getClientNote(DeviceGrantType.OAUTH2_DEVICE_VERIFIED_USER_CODE);
String userSessionId = clientSession.getUserSession().getId();
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- if (!store.approve(realm, verifiedUserCode, userSessionId, null)) {
+ if (!approveUserCode(session, realm, verifiedUserCode, userSessionId, null)) {
// Already expired and removed in the store
return Response.status(302).location(
uriBuilder.queryParam(OAuth2Constants.ERROR, OAuthErrorException.EXPIRED_TOKEN)
@@ -133,7 +131,7 @@ public class DeviceGrantType {
}
// Now, remove the verified user code
- store.removeUserCode(realm, verifiedUserCode);
+ removeDeviceByUserCode(session, realm, verifiedUserCode);
return Response.status(302).location(
uriBuilder.build(realm.getName())
@@ -145,6 +143,51 @@ public class DeviceGrantType {
return flow != null;
}
+ public static OAuth2DeviceCodeModel getDeviceByDeviceCode(KeycloakSession session, RealmModel realm, String deviceCode) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ Map notes = singleUseStore.get(OAuth2DeviceCodeModel.createKey(deviceCode));
+ return notes != null ? OAuth2DeviceCodeModel.fromCache(realm, deviceCode, notes) : null;
+ }
+
+ public static void removeDeviceByDeviceCode(KeycloakSession session, String deviceCode) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ singleUseStore.remove(OAuth2DeviceCodeModel.createKey(deviceCode));
+ }
+
+ public static void removeDeviceByUserCode(KeycloakSession session, RealmModel realm, String userCode) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ singleUseStore.remove(OAuth2DeviceUserCodeModel.createKey(realm, userCode));
+ }
+
+ public static boolean isPollingAllowed(KeycloakSession session, OAuth2DeviceCodeModel deviceCodeModel) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ return singleUseStore.putIfAbsent(deviceCodeModel.serializePollingKey(), deviceCodeModel.getPollingInterval());
+ }
+
+ public static boolean approveUserCode(KeycloakSession session, RealmModel realm, String userCode, String userSessionId, Map additionalParams) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ OAuth2DeviceCodeModel deviceCodeModel = DeviceEndpoint.getDeviceByUserCode(session, realm, userCode);
+
+ if (deviceCodeModel != null) {
+ OAuth2DeviceCodeModel approvedDeviceCode = deviceCodeModel.approve(userSessionId, additionalParams);
+ return singleUseStore.replace(approvedDeviceCode.serializeKey(), approvedDeviceCode.toMap());
+ }
+
+ return false;
+ }
+
+ public static boolean denyUserCode(KeycloakSession session, RealmModel realm, String userCode) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ OAuth2DeviceCodeModel deviceCodeModel = DeviceEndpoint.getDeviceByUserCode(session, realm, userCode);
+
+ if (deviceCodeModel != null) {
+ OAuth2DeviceCodeModel deniedDeviceCode = deviceCodeModel.deny();
+ return singleUseStore.replace(deniedDeviceCode.serializeKey(), deniedDeviceCode.toMap());
+ }
+
+ return false;
+ }
+
private MultivaluedMap formParams;
private ClientModel client;
@@ -182,8 +225,7 @@ public class DeviceGrantType {
"Missing parameter: " + OAuth2Constants.DEVICE_CODE, Response.Status.BAD_REQUEST);
}
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- OAuth2DeviceCodeModel deviceCodeModel = store.getByDeviceCode(realm, deviceCode);
+ OAuth2DeviceCodeModel deviceCodeModel = getDeviceByDeviceCode(session, realm, deviceCode);
if (deviceCodeModel == null) {
event.error(Errors.INVALID_OAUTH2_DEVICE_CODE);
@@ -197,7 +239,7 @@ public class DeviceGrantType {
Response.Status.BAD_REQUEST);
}
- if (!store.isPollingAllowed(deviceCodeModel)) {
+ if (!isPollingAllowed(session, deviceCodeModel)) {
event.error(Errors.SLOW_DOWN);
throw new CorsErrorResponseException(cors, OAuthErrorException.SLOW_DOWN, "Slow down", Response.Status.BAD_REQUEST);
}
@@ -245,7 +287,7 @@ public class DeviceGrantType {
}
// Now, remove the device code
- store.removeDeviceCode(realm, deviceCode);
+ removeDeviceByDeviceCode(session, deviceCode);
UserModel user = userSession.getUser();
if (user == null) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/grants/device/endpoints/DeviceEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/grants/device/endpoints/DeviceEndpoint.java
index 662cb1c0909..6bb4630d69f 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/grants/device/endpoints/DeviceEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/grants/device/endpoints/DeviceEndpoint.java
@@ -30,11 +30,12 @@ import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuth2DeviceCodeModel;
-import org.keycloak.models.OAuth2DeviceTokenStoreProvider;
import org.keycloak.models.OAuth2DeviceUserCodeModel;
import org.keycloak.models.OAuth2DeviceUserCodeProvider;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.protocol.AuthorizationEndpointBase;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.endpoints.AuthorizationEndpointChecker;
@@ -70,6 +71,8 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
+import java.util.Map;
+
import static org.keycloak.protocol.oidc.grants.device.DeviceGrantType.OAUTH2_DEVICE_USER_CODE;
/**
@@ -161,8 +164,10 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
// To inform "expired_token" to the client, the lifespan of the cache provider is longer than device code
int lifespanSeconds = expiresIn + interval + 10;
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
- store.put(deviceCode, userCode, lifespanSeconds);
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+
+ singleUseStore.put(deviceCode.serializeKey(), lifespanSeconds, deviceCode.toMap());
+ singleUseStore.put(userCode.serializeKey(), lifespanSeconds, userCode.serializeValue());
try {
String deviceUrl = DeviceGrantType.oauth2DeviceVerificationUrl(session.getContext().getUri()).build(realm.getName())
@@ -212,10 +217,9 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
} else {
// code exists, probably due to using a verification_uri_complete. Start the authentication considering the client
// that started the flow.
- OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
OAuth2DeviceUserCodeProvider userCodeProvider = session.getProvider(OAuth2DeviceUserCodeProvider.class);
String formattedUserCode = userCodeProvider.format(userCode);
- OAuth2DeviceCodeModel deviceCode = store.getByUserCode(realm, formattedUserCode);
+ OAuth2DeviceCodeModel deviceCode = getDeviceByUserCode(session, realm, formattedUserCode);
if (deviceCode == null) {
return invalidUserCodeResponse(Messages.OAUTH2_DEVICE_INVALID_USER_CODE, "device code not found (it may already have been used)");
@@ -287,6 +291,21 @@ public class DeviceEndpoint extends AuthorizationEndpointBase implements RealmRe
}
}
+ public static OAuth2DeviceCodeModel getDeviceByUserCode(KeycloakSession session, RealmModel realm, String userCode) {
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ Map notes = singleUseStore.get(OAuth2DeviceUserCodeModel.createKey(realm, userCode));
+
+ if (notes != null) {
+ OAuth2DeviceUserCodeModel data = OAuth2DeviceUserCodeModel.fromCache(realm, userCode, notes);
+ String deviceCode = data.getDeviceCode();
+ notes = singleUseStore.get(OAuth2DeviceCodeModel.createKey(deviceCode));
+
+ return notes != null ? OAuth2DeviceCodeModel.fromCache(realm, deviceCode, notes) : null;
+ }
+
+ return null;
+ }
+
/**
* @param errorMessage Message code for the verification page
* @param reason For event details; not exposed to end user
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/ParEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/ParEndpoint.java
index adf58b6ed82..6aaf8759ac0 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/ParEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/ParEndpoint.java
@@ -24,7 +24,7 @@ import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.headers.SecurityHeadersProvider;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.PushedAuthzRequestStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.endpoints.AuthorizationEndpointChecker;
import org.keycloak.protocol.oidc.endpoints.request.AuthorizationEndpointRequest;
@@ -146,8 +146,8 @@ public class ParEndpoint extends AbstractParEndpoint {
Map params = new HashMap<>();
- UUID key = UUID.randomUUID();
- String requestUri = REQUEST_URI_PREFIX + key.toString();
+ String key = UUID.randomUUID().toString();
+ String requestUri = REQUEST_URI_PREFIX + key;
int expiresIn = realm.getParPolicy().getRequestUriLifespan();
@@ -158,8 +158,8 @@ public class ParEndpoint extends AbstractParEndpoint {
});
params.put(PAR_CREATED_TIME, String.valueOf(System.currentTimeMillis()));
- PushedAuthzRequestStoreProvider parStore = session.getProvider(PushedAuthzRequestStoreProvider.class);
- parStore.put(key, expiresIn, params);
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ singleUseStore.put(key, expiresIn, params);
ParResponse parResponse = new ParResponse(requestUri, expiresIn);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/request/AuthzEndpointParParser.java b/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/request/AuthzEndpointParParser.java
index a19f6961657..986e244d750 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/request/AuthzEndpointParParser.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/par/endpoints/request/AuthzEndpointParParser.java
@@ -20,13 +20,12 @@ package org.keycloak.protocol.oidc.par.endpoints.request;
import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import org.jboss.logging.Logger;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.PushedAuthzRequestStoreProvider;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.endpoints.request.AuthorizationEndpointRequest;
import org.keycloak.protocol.oidc.endpoints.request.AuthzEndpointRequestObjectParser;
@@ -51,15 +50,15 @@ public class AuthzEndpointParParser extends AuthzEndpointRequestParser {
public AuthzEndpointParParser(KeycloakSession session, ClientModel client, String requestUri) {
this.session = session;
this.client = client;
- PushedAuthzRequestStoreProvider parStore = session.getProvider(PushedAuthzRequestStoreProvider.class);
- UUID key;
+ SingleUseObjectProvider singleUseStore = session.getProvider(SingleUseObjectProvider.class);
+ String key;
try {
- key = UUID.fromString(requestUri.substring(ParEndpoint.REQUEST_URI_PREFIX_LENGTH));
+ key = requestUri.substring(ParEndpoint.REQUEST_URI_PREFIX_LENGTH);
} catch (RuntimeException re) {
logger.warnf(re,"Unable to parse request_uri: %s", requestUri);
throw new RuntimeException("Unable to parse request_uri");
}
- Map retrievedRequest = parStore.remove(key);
+ Map retrievedRequest = singleUseStore.remove(key);
if (retrievedRequest == null) {
throw new RuntimeException("PAR not found. not issued or used multiple times.");
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2Code.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2Code.java
index fd9159922dd..83050aaec15 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2Code.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2Code.java
@@ -19,7 +19,6 @@ package org.keycloak.protocol.oidc.utils;
import java.util.HashMap;
import java.util.Map;
-import java.util.UUID;
/**
* Data associated with the oauth2 code.
@@ -40,7 +39,7 @@ public class OAuth2Code {
private static final String CODE_CHALLENGE_NOTE = "code_challenge";
private static final String CODE_CHALLENGE_METHOD_NOTE = "code_challenge_method";
- private final UUID id;
+ private final String id;
private final int expiration;
@@ -55,7 +54,7 @@ public class OAuth2Code {
private final String codeChallengeMethod;
- public OAuth2Code(UUID id, int expiration, String nonce, String scope, String redirectUriParam,
+ public OAuth2Code(String id, int expiration, String nonce, String scope, String redirectUriParam,
String codeChallenge, String codeChallengeMethod) {
this.id = id;
this.expiration = expiration;
@@ -68,7 +67,7 @@ public class OAuth2Code {
private OAuth2Code(Map data) {
- id = UUID.fromString(data.get(ID_NOTE));
+ id = data.get(ID_NOTE);
expiration = Integer.parseInt(data.get(EXPIRATION_NOTE));
nonce = data.get(NONCE_NOTE);
scope = data.get(SCOPE_NOTE);
@@ -98,7 +97,7 @@ public class OAuth2Code {
}
- public UUID getId() {
+ public String getId() {
return id;
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2CodeParser.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2CodeParser.java
index d5657897821..75a48148f2e 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2CodeParser.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/OAuth2CodeParser.java
@@ -18,7 +18,6 @@
package org.keycloak.protocol.oidc.utils;
import java.util.Map;
-import java.util.UUID;
import java.util.regex.Pattern;
import org.jboss.logging.Logger;
@@ -26,9 +25,9 @@ import org.keycloak.common.util.Time;
import org.keycloak.events.Details;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.AuthenticatedClientSessionModel;
-import org.keycloak.models.CodeToTokenStoreProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserSessionModel;
import org.keycloak.services.managers.UserSessionCrossDCManager;
@@ -51,16 +50,16 @@ public class OAuth2CodeParser {
* @return code parameter to be used in OAuth2 handshake
*/
public static String persistCode(KeycloakSession session, AuthenticatedClientSessionModel clientSession, OAuth2Code codeData) {
- CodeToTokenStoreProvider codeStore = session.getProvider(CodeToTokenStoreProvider.class);
+ SingleUseObjectProvider codeStore = session.getProvider(SingleUseObjectProvider.class);
- UUID key = codeData.getId();
+ String key = codeData.getId();
if (key == null) {
throw new IllegalStateException("ID not present in the data");
}
Map serialized = codeData.serializeCode();
codeStore.put(key, clientSession.getUserSession().getRealm().getAccessCodeLifespan(), serialized);
- return key.toString() + "." + clientSession.getUserSession().getId() + "." + clientSession.getClient().getId();
+ return key + "." + clientSession.getUserSession().getId() + "." + clientSession.getClient().getId();
}
@@ -91,9 +90,9 @@ public class OAuth2CodeParser {
event.session(userSessionId);
// Parse UUID
- UUID codeUUID;
+ String codeUUID;
try {
- codeUUID = UUID.fromString(parsed[0]);
+ codeUUID = parsed[0];
} catch (IllegalArgumentException re) {
logger.warn("Invalid format of the UUID in the code");
return result.illegalCode();
@@ -111,7 +110,7 @@ public class OAuth2CodeParser {
result.clientSession = userSession.getAuthenticatedClientSessionByClient(clientUUID);
- CodeToTokenStoreProvider codeStore = session.getProvider(CodeToTokenStoreProvider.class);
+ SingleUseObjectProvider codeStore = session.getProvider(SingleUseObjectProvider.class);
Map codeData = codeStore.remove(codeUUID);
// Either code not available or was already used
diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index 44b813d9f20..7797416d08d 100755
--- a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -17,7 +17,6 @@
package org.keycloak.protocol.saml;
-import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
@@ -43,7 +42,7 @@ import org.keycloak.models.KeyManager;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.LoginProtocol;
@@ -85,7 +84,6 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
-import java.io.InputStream;
import java.net.URI;
import java.security.PublicKey;
import java.util.ArrayList;
@@ -140,6 +138,9 @@ public class SamlProtocol implements LoginProtocol {
public static final String SAML_LOGIN_REQUEST_FORCEAUTHN = "SAML_LOGIN_REQUEST_FORCEAUTHN";
public static final String SAML_FORCEAUTHN_REQUIREMENT = "true";
public static final String SAML_LOGOUT_INITIATOR_CLIENT_ID = "SAML_LOGOUT_INITIATOR_CLIENT_ID";
+ public static final String USER_SESSION_ID = "userSessionId";
+ public static final String CLIENT_SESSION_ID = "clientSessionId";
+
protected static final Logger logger = Logger.getLogger(SamlProtocol.class);
@@ -154,7 +155,7 @@ public class SamlProtocol implements LoginProtocol {
protected EventBuilder event;
protected ArtifactResolver artifactResolver;
- protected SamlArtifactSessionMappingStoreProvider artifactSessionMappingStore;
+ protected SingleUseObjectProvider singleUseStore;
@Override
public SamlProtocol setSession(KeycloakSession session) {
@@ -193,11 +194,11 @@ public class SamlProtocol implements LoginProtocol {
return artifactResolver;
}
- private SamlArtifactSessionMappingStoreProvider getArtifactSessionMappingStore() {
- if (artifactSessionMappingStore == null) {
- artifactSessionMappingStore = session.getProvider(SamlArtifactSessionMappingStoreProvider.class);
+ private SingleUseObjectProvider getSingleUseStore() {
+ if (singleUseStore == null) {
+ singleUseStore = session.getProvider(SingleUseObjectProvider.class);
}
- return artifactSessionMappingStore;
+ return singleUseStore;
}
@Override
@@ -929,7 +930,10 @@ public class SamlProtocol implements LoginProtocol {
// Create artifact and store session mapping
SAMLDataMarshaller marshaller = new SAMLDataMarshaller();
String artifact = getArtifactResolver().buildArtifact(clientSessionModel, entityId, marshaller.serialize(artifactResponseType));
- getArtifactSessionMappingStore().put(artifact, realm.getAccessCodeLifespan(), clientSessionModel);
+ HashMap notes = new HashMap<>();
+ notes.put(USER_SESSION_ID, clientSessionModel.getUserSession().getId());
+ notes.put(CLIENT_SESSION_ID, clientSessionModel.getClient().getId());
+ getSingleUseStore().put(artifact, realm.getAccessCodeLifespan(), notes);
return artifact;
}
diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlService.java b/services/src/main/java/org/keycloak/protocol/saml/SamlService.java
index 387ecb8f953..a6fb156ac02 100755
--- a/services/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -60,8 +60,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.KeycloakUriInfo;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.SamlArtifactSessionMappingModel;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.AuthorizationEndpointBase;
import org.keycloak.protocol.LoginProtocol;
@@ -137,6 +136,7 @@ import java.security.PublicKey;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -1104,8 +1104,8 @@ public class SamlService extends AuthorizationEndpointBase {
}
- private SamlArtifactSessionMappingStoreProvider getArtifactSessionMappingStore() {
- return session.getProvider(SamlArtifactSessionMappingStoreProvider.class);
+ private SingleUseObjectProvider getSingleUseStore() {
+ return session.getProvider(SingleUseObjectProvider.class);
}
/**
@@ -1136,26 +1136,27 @@ public class SamlService extends AuthorizationEndpointBase {
}
// Obtain details of session that issued artifact and check if it corresponds to issuer of Resolve message
- SamlArtifactSessionMappingModel sessionMapping = getArtifactSessionMappingStore().get(artifact);
+ Map sessionMapping = getSingleUseStore().get(artifact);
if (sessionMapping == null) {
logger.errorf("No data stored for artifact %s", artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
- UserSessionModel userSessionModel = session.sessions().getUserSession(realm, sessionMapping.getUserSessionId());
+ UserSessionModel userSessionModel = session.sessions().getUserSession(realm, sessionMapping.get(SamlProtocol.USER_SESSION_ID));
if (userSessionModel == null) {
- logger.errorf("UserSession with id: %s, that corresponds to artifact: %s does not exist.", sessionMapping.getUserSessionId(), artifact);
+ logger.errorf("UserSession with id: %s, that corresponds to artifact: %s does not exist.", sessionMapping.get(SamlProtocol.USER_SESSION_ID), artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
- AuthenticatedClientSessionModel clientSessionModel = userSessionModel.getAuthenticatedClientSessions().get(sessionMapping.getClientSessionId());
+ AuthenticatedClientSessionModel clientSessionModel = userSessionModel.getAuthenticatedClientSessions().get(sessionMapping.get(SamlProtocol.CLIENT_SESSION_ID));
if (clientSessionModel == null) {
- logger.errorf("ClientSession with id: %s, that corresponds to artifact: %s and UserSession: %s does not exist.", sessionMapping.getClientSessionId(), artifact, sessionMapping.getUserSessionId());
+ logger.errorf("ClientSession with id: %s, that corresponds to artifact: %s and UserSession: %s does not exist.",
+ sessionMapping.get(SamlProtocol.CLIENT_SESSION_ID), artifact, sessionMapping.get(SamlProtocol.USER_SESSION_ID));
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
- ClientModel clientModel = getAndCheckClientModel(sessionMapping.getClientSessionId(), artifactResolveMessage.getIssuer().getValue());
+ ClientModel clientModel = getAndCheckClientModel(sessionMapping.get(SamlProtocol.CLIENT_SESSION_ID), artifactResolveMessage.getIssuer().getValue());
SamlClient samlClient = new SamlClient(clientModel);
// Check signature within ArtifactResolve request if client requires it
@@ -1178,7 +1179,9 @@ public class SamlService extends AuthorizationEndpointBase {
}
// Artifact is successfully resolved, we can remove session mapping from storage
- getArtifactSessionMappingStore().remove(artifact);
+ if (getSingleUseStore().remove(artifact) == null) {
+ logger.debugf("Artifact %s was already removed", artifact);
+ }
Document artifactResponseDocument = null;
ArtifactResponseType artifactResponseType = null;
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/HandleArtifactStepBuilder.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/HandleArtifactStepBuilder.java
index cf744c9839b..26d12d0460a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/HandleArtifactStepBuilder.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/HandleArtifactStepBuilder.java
@@ -11,7 +11,8 @@ import org.apache.http.util.EntityUtils;
import org.keycloak.common.util.KeyUtils;
import org.keycloak.dom.saml.v2.assertion.NameIDType;
import org.keycloak.dom.saml.v2.protocol.ArtifactResolveType;
-import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
+import org.keycloak.models.SingleUseObjectProvider;
+import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.protocol.saml.SamlService;
import org.keycloak.protocol.saml.profile.util.Soap;
import org.keycloak.saml.BaseSAML2BindingBuilder;
@@ -195,8 +196,8 @@ public class HandleArtifactStepBuilder extends SamlDocumentStepBuilder session.getProvider(SamlArtifactSessionMappingStoreProvider.class).get(artifact).getUserSessionId());
- sessionStateChecker.setClientSessionProvider(session -> session.getProvider(SamlArtifactSessionMappingStoreProvider.class).get(artifact).getClientSessionId());
+ sessionStateChecker.setUserSessionProvider(session -> session.getProvider(SingleUseObjectProvider.class).get(artifact).get(SamlProtocol.USER_SESSION_ID));
+ sessionStateChecker.setClientSessionProvider(session -> session.getProvider(SingleUseObjectProvider.class).get(artifact).get(SamlProtocol.CLIENT_SESSION_ID));
}
HttpPost post = Soap.createMessage().addToBody(DocumentUtil.getDocument(transformed)).buildHttpPost(authServerSamlUrl);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2DeviceAuthorizationGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2DeviceAuthorizationGrantTest.java
index a2367ec03cd..4ff15c85b8c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2DeviceAuthorizationGrantTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2DeviceAuthorizationGrantTest.java
@@ -707,7 +707,7 @@ public class OAuth2DeviceAuthorizationGrantTest extends AbstractKeycloakTest {
}
@Test
- public void testPooling() throws Exception {
+ public void testPolling() throws Exception {
getTestingClient().testing().setTestingInfinispanTimeService();
try {