Hot Rod map storage: Single-use (action token) no-downtime store
This commit is contained in:
parent
a102e28dbb
commit
df72cf72f2
11 changed files with 297 additions and 22 deletions
|
@ -26,6 +26,7 @@ import org.keycloak.authorization.model.ResourceServer;
|
|||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.component.AmphibianProviderFactory;
|
||||
import org.keycloak.models.ActionTokenValueModel;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.events.admin.AdminEvent;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
|
@ -66,6 +67,7 @@ import org.keycloak.models.map.realm.entity.MapRequiredActionProviderEntity;
|
|||
import org.keycloak.models.map.realm.entity.MapRequiredCredentialEntity;
|
||||
import org.keycloak.models.map.realm.entity.MapWebAuthnPolicyEntity;
|
||||
import org.keycloak.models.map.role.MapRoleEntity;
|
||||
import org.keycloak.models.map.singleUseObject.MapSingleUseObjectEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.authSession.HotRodAuthenticationSessionEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.authSession.HotRodRootAuthenticationSessionEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.authSession.HotRodRootAuthenticationSessionEntityDelegate;
|
||||
|
@ -116,6 +118,8 @@ import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodOTPPolicyEntity
|
|||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequiredActionProviderEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequiredCredentialEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodWebAuthnPolicyEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserConsentEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserCredentialEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserEntity;
|
||||
|
@ -159,6 +163,8 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
|
|||
|
||||
.constructor(MapRoleEntity.class, HotRodRoleEntityDelegate::new)
|
||||
|
||||
.constructor(MapSingleUseObjectEntity.class, HotRodSingleUseObjectEntityDelegate::new)
|
||||
|
||||
.constructor(MapUserEntity.class, HotRodUserEntityDelegate::new)
|
||||
.constructor(MapUserCredentialEntity.class, HotRodUserCredentialEntityDelegate::new)
|
||||
.constructor(MapUserFederatedIdentityEntity.class, HotRodUserFederatedIdentityEntityDelegate::new)
|
||||
|
@ -242,6 +248,12 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
|
|||
HotRodRealmEntity.class,
|
||||
HotRodRealmEntityDelegate::new));
|
||||
|
||||
// single-use object storage descriptor
|
||||
ENTITY_DESCRIPTOR_MAP.put(ActionTokenValueModel.class,
|
||||
new HotRodEntityDescriptor<>(ActionTokenValueModel.class,
|
||||
HotRodSingleUseObjectEntity.class,
|
||||
HotRodSingleUseObjectEntityDelegate::new));
|
||||
|
||||
// User sessions descriptor
|
||||
ENTITY_DESCRIPTOR_MAP.put(UserSessionModel.class,
|
||||
new HotRodEntityDescriptor<>(UserSessionModel.class,
|
||||
|
@ -339,6 +351,8 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
|
|||
HotRodMapStorage clientSessionStore = getHotRodStorage(session, AuthenticatedClientSessionModel.class);
|
||||
return new HotRodUserSessionMapStorage(clientSessionStore, connectionProvider.getRemoteCache(entityDescriptor.getCacheName()), StringKeyConverter.StringKey.INSTANCE, entityDescriptor, CLONER);
|
||||
|
||||
} else if (modelType == ActionTokenValueModel.class) {
|
||||
return new SingleUseObjectHotRodMapStorage(connectionProvider.getRemoteCache(entityDescriptor.getCacheName()), StringKeyConverter.StringKey.INSTANCE, entityDescriptor, CLONER);
|
||||
}
|
||||
return new HotRodMapStorage<>(connectionProvider.getRemoteCache(entityDescriptor.getCacheName()), StringKeyConverter.StringKey.INSTANCE, entityDescriptor, CLONER);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2022 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.map.storage.hotRod;
|
||||
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
import org.keycloak.models.ActionTokenValueModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.map.common.AbstractEntity;
|
||||
import org.keycloak.models.map.common.DeepCloner;
|
||||
import org.keycloak.models.map.common.StringKeyConverter;
|
||||
import org.keycloak.models.map.storage.chm.MapModelCriteriaBuilder;
|
||||
import org.keycloak.models.map.storage.chm.SingleUseObjectKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.QueryParameters;
|
||||
import org.keycloak.models.map.storage.chm.MapFieldPredicates;
|
||||
import org.keycloak.models.map.storage.chm.SingleUseObjectModelCriteriaBuilder;
|
||||
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
||||
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate;
|
||||
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDescriptor;
|
||||
import org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntityDelegate;
|
||||
import org.keycloak.storage.SearchableModelField;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||
*/
|
||||
public class SingleUseObjectHotRodMapStorage<K, E extends AbstractHotRodEntity, V extends HotRodEntityDelegate<E> & AbstractEntity, M>
|
||||
extends HotRodMapStorage<String, HotRodSingleUseObjectEntity, HotRodSingleUseObjectEntityDelegate, ActionTokenValueModel> {
|
||||
|
||||
private final StringKeyConverter<String> keyConverter;
|
||||
private final HotRodEntityDescriptor<HotRodSingleUseObjectEntity, HotRodSingleUseObjectEntityDelegate> storedEntityDescriptor;
|
||||
private final DeepCloner cloner;
|
||||
|
||||
public SingleUseObjectHotRodMapStorage(RemoteCache<String, HotRodSingleUseObjectEntity> remoteCache, StringKeyConverter<String> keyConverter,
|
||||
HotRodEntityDescriptor<HotRodSingleUseObjectEntity, HotRodSingleUseObjectEntityDelegate> storedEntityDescriptor,
|
||||
DeepCloner cloner) {
|
||||
super(remoteCache, keyConverter, storedEntityDescriptor, cloner);
|
||||
this.keyConverter = keyConverter;
|
||||
this.storedEntityDescriptor = storedEntityDescriptor;
|
||||
this.cloner = cloner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapKeycloakTransaction<HotRodSingleUseObjectEntityDelegate, ActionTokenValueModel> createTransaction(KeycloakSession session) {
|
||||
MapKeycloakTransaction<HotRodSingleUseObjectEntityDelegate, ActionTokenValueModel> transaction = session.getAttribute("map-transaction-" + hashCode(), MapKeycloakTransaction.class);
|
||||
|
||||
if (transaction == null) {
|
||||
Map<SearchableModelField<? super ActionTokenValueModel>, MapModelCriteriaBuilder.UpdatePredicatesFunc<K, HotRodSingleUseObjectEntityDelegate, ActionTokenValueModel>> fieldPredicates =
|
||||
MapFieldPredicates.getPredicates((Class<ActionTokenValueModel>) storedEntityDescriptor.getModelTypeClass());
|
||||
transaction = new SingleUseObjectKeycloakTransaction(this, keyConverter, cloner, fieldPredicates);
|
||||
session.setAttribute("map-transaction-" + hashCode(), transaction);
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HotRodSingleUseObjectEntityDelegate create(HotRodSingleUseObjectEntityDelegate value) {
|
||||
if (value.getId() == null) {
|
||||
if (value.getUserId() != null && value.getActionId() != null && value.getActionVerificationNonce() != null) {
|
||||
value.setId(value.getUserId() + ":" + value.getActionId() + ":" + value.getActionVerificationNonce());
|
||||
}
|
||||
}
|
||||
return super.create(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<HotRodSingleUseObjectEntityDelegate> read(QueryParameters<ActionTokenValueModel> queryParameters) {
|
||||
DefaultModelCriteria<ActionTokenValueModel> criteria = queryParameters.getModelCriteriaBuilder();
|
||||
|
||||
if (criteria == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
SingleUseObjectModelCriteriaBuilder mcb = criteria.flashToModelCriteriaBuilder(createSingleUseObjectCriteriaBuilder());
|
||||
if (mcb.isValid()) {
|
||||
HotRodSingleUseObjectEntityDelegate value = read(mcb.getKey());
|
||||
|
||||
return value != null && value.getHotRodEntity() != null ? Stream.of(value) : Stream.empty();
|
||||
}
|
||||
|
||||
return super.read(queryParameters);
|
||||
}
|
||||
|
||||
private SingleUseObjectModelCriteriaBuilder createSingleUseObjectCriteriaBuilder() {
|
||||
return new SingleUseObjectModelCriteriaBuilder();
|
||||
}
|
||||
|
||||
}
|
|
@ -54,6 +54,7 @@ import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequiredCredent
|
|||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequirement;
|
||||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodWebAuthnPolicyEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.role.HotRodRoleEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserConsentEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserCredentialEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserEntity;
|
||||
|
@ -110,6 +111,9 @@ import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntit
|
|||
HotRodWebAuthnPolicyEntity.class,
|
||||
HotRodRealmEntity.class,
|
||||
|
||||
// single-use objects
|
||||
HotRodSingleUseObjectEntity.class,
|
||||
|
||||
// User sessions
|
||||
HotRodUserSessionEntity.class,
|
||||
HotRodSessionState.class,
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2022 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.map.storage.hotRod.singleUseObject;
|
||||
|
||||
import org.infinispan.protostream.annotations.ProtoDoc;
|
||||
import org.infinispan.protostream.annotations.ProtoField;
|
||||
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
|
||||
import org.keycloak.models.map.singleUseObject.MapSingleUseObjectEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
||||
import org.keycloak.models.map.storage.hotRod.common.HotRodPair;
|
||||
import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelegateImpl;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@GenerateHotRodEntityImplementation(
|
||||
implementInterface = "org.keycloak.models.map.singleUseObject.MapSingleUseObjectEntity",
|
||||
inherits = "org.keycloak.models.map.storage.hotRod.singleUseObject.HotRodSingleUseObjectEntity.AbstractHotRodSingleUseObjectEntityDelegate"
|
||||
)
|
||||
@ProtoDoc("@Indexed")
|
||||
public class HotRodSingleUseObjectEntity extends AbstractHotRodEntity {
|
||||
|
||||
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||
@ProtoField(number = 1)
|
||||
public Integer entityVersion = 1;
|
||||
|
||||
@ProtoField(number = 2)
|
||||
public String id;
|
||||
|
||||
@ProtoField(number = 3)
|
||||
public String userId;
|
||||
|
||||
@ProtoField(number = 4)
|
||||
public String actionId;
|
||||
|
||||
@ProtoField(number = 5)
|
||||
public String actionVerificationNonce;
|
||||
|
||||
@ProtoField(number = 6)
|
||||
public Long expiration;
|
||||
|
||||
@ProtoField(number = 7)
|
||||
public Set<HotRodPair<String, String>> notes;
|
||||
|
||||
public static abstract class AbstractHotRodSingleUseObjectEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodSingleUseObjectEntity> implements MapSingleUseObjectEntity {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
HotRodSingleUseObjectEntity hotRodEntity = getHotRodEntity();
|
||||
return hotRodEntity != null ? hotRodEntity.id : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
HotRodSingleUseObjectEntity entity = getHotRodEntity();
|
||||
if (entity.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||
entity.id = id;
|
||||
entity.updated |= id != null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return HotRodSingleUseObjectEntityDelegate.entityEquals(this, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return HotRodSingleUseObjectEntityDelegate.entityHashCode(this);
|
||||
}
|
||||
}
|
|
@ -116,5 +116,13 @@
|
|||
</indexed-entities>
|
||||
</indexing>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="single-use-objects" mode="SYNC">
|
||||
<indexing>
|
||||
<indexed-entities>
|
||||
<indexed-entity>kc.HotRodSingleUseObjectEntity</indexed-entity>
|
||||
</indexed-entities>
|
||||
</indexing>
|
||||
<encoding media-type="application/x-protostream"/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
</infinispan>
|
||||
|
|
|
@ -118,5 +118,13 @@
|
|||
</indexed-entities>
|
||||
</indexing>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="single-use-objects" mode="SYNC">
|
||||
<indexing>
|
||||
<indexed-entities>
|
||||
<indexed-entity>kc.HotRodSingleUseObjectEntity</indexed-entity>
|
||||
</indexed-entities>
|
||||
</indexing>
|
||||
<encoding media-type="application/x-protostream"/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
</infinispan>
|
||||
|
|
|
@ -26,9 +26,7 @@ import org.keycloak.models.map.singleUseObject.MapSingleUseObjectEntity;
|
|||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.QueryParameters;
|
||||
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
||||
import org.keycloak.storage.SearchableModelField;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -44,7 +42,13 @@ public class SingleUseObjectConcurrentHashMapStorage<K, V extends AbstractEntity
|
|||
@SuppressWarnings("unchecked")
|
||||
public MapKeycloakTransaction<MapSingleUseObjectEntity, ActionTokenValueModel> createTransaction(KeycloakSession session) {
|
||||
MapKeycloakTransaction<MapSingleUseObjectEntity, ActionTokenValueModel> actionTokenTransaction = session.getAttribute("map-transaction-" + hashCode(), MapKeycloakTransaction.class);
|
||||
return actionTokenTransaction == null ? new SingleUseObjectConcurrentHashMapStorage.Transaction(getKeyConverter(), cloner, fieldPredicates) : actionTokenTransaction;
|
||||
|
||||
if (actionTokenTransaction == null) {
|
||||
actionTokenTransaction = new SingleUseObjectKeycloakTransaction(this, keyConverter, cloner, fieldPredicates);
|
||||
session.setAttribute("map-transaction-" + hashCode(), actionTokenTransaction);
|
||||
}
|
||||
|
||||
return actionTokenTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,21 +82,4 @@ public class SingleUseObjectConcurrentHashMapStorage<K, V extends AbstractEntity
|
|||
return new SingleUseObjectModelCriteriaBuilder();
|
||||
}
|
||||
|
||||
private class Transaction extends ConcurrentHashMapKeycloakTransaction<K, MapSingleUseObjectEntity, ActionTokenValueModel> {
|
||||
|
||||
public Transaction(StringKeyConverter<K> keyConverter, DeepCloner cloner,
|
||||
Map<SearchableModelField<? super ActionTokenValueModel>, MapModelCriteriaBuilder.UpdatePredicatesFunc<K, MapSingleUseObjectEntity, ActionTokenValueModel>> fieldPredicates) {
|
||||
super(SingleUseObjectConcurrentHashMapStorage.this, keyConverter, cloner, fieldPredicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapSingleUseObjectEntity create(MapSingleUseObjectEntity value) {
|
||||
if (value.getId() == null) {
|
||||
if (value.getUserId() != null && value.getActionId() != null && value.getActionVerificationNonce() != null) {
|
||||
value.setId(value.getUserId() + ":" + value.getActionId() + ":" + value.getActionVerificationNonce());
|
||||
}
|
||||
}
|
||||
return super.create(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2022 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.map.storage.chm;
|
||||
|
||||
import org.keycloak.models.ActionTokenValueModel;
|
||||
import org.keycloak.models.map.common.DeepCloner;
|
||||
import org.keycloak.models.map.common.StringKeyConverter;
|
||||
import org.keycloak.models.map.singleUseObject.MapSingleUseObjectEntity;
|
||||
import org.keycloak.storage.SearchableModelField;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||
*/
|
||||
public class SingleUseObjectKeycloakTransaction<K> extends ConcurrentHashMapKeycloakTransaction<K, MapSingleUseObjectEntity, ActionTokenValueModel> {
|
||||
|
||||
public SingleUseObjectKeycloakTransaction(ConcurrentHashMapCrudOperations<MapSingleUseObjectEntity, ActionTokenValueModel> map,
|
||||
StringKeyConverter<K> keyConverter,
|
||||
DeepCloner cloner,
|
||||
Map<SearchableModelField<? super ActionTokenValueModel>,
|
||||
MapModelCriteriaBuilder.UpdatePredicatesFunc<K, MapSingleUseObjectEntity, ActionTokenValueModel>> fieldPredicates) {
|
||||
super(map, keyConverter, cloner, fieldPredicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapSingleUseObjectEntity create(MapSingleUseObjectEntity value) {
|
||||
if (value.getId() == null) {
|
||||
if (value.getUserId() != null && value.getActionId() != null && value.getActionVerificationNonce() != null) {
|
||||
value.setId(value.getUserId() + ":" + value.getActionId() + ":" + value.getActionVerificationNonce());
|
||||
}
|
||||
}
|
||||
return super.create(value);
|
||||
}
|
||||
}
|
|
@ -1507,6 +1507,8 @@
|
|||
<keycloak.userSession.map.storage.provider>hotrod</keycloak.userSession.map.storage.provider>
|
||||
<keycloak.authorization.map.storage.provider>hotrod</keycloak.authorization.map.storage.provider>
|
||||
<keycloak.eventStore.map.storage.provider>hotrod</keycloak.eventStore.map.storage.provider>
|
||||
<keycloak.actionToken.map.storage.provider>hotrod</keycloak.actionToken.map.storage.provider>
|
||||
<keycloak.singleUseObject.map.storage.provider>hotrod</keycloak.singleUseObject.map.storage.provider>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -114,5 +114,13 @@
|
|||
</indexed-entities>
|
||||
</indexing>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="single-use-objects" mode="SYNC">
|
||||
<indexing>
|
||||
<indexed-entities>
|
||||
<indexed-entity>kc.HotRodSingleUseObjectEntity</indexed-entity>
|
||||
</indexed-entities>
|
||||
</indexing>
|
||||
<encoding media-type="application/x-protostream"/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
</infinispan>
|
||||
|
|
|
@ -76,8 +76,8 @@ public class HotRodMapStorage extends KeycloakModelParameters {
|
|||
@Override
|
||||
public void updateConfig(Config cf) {
|
||||
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi(ActionTokenStoreSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi(ActionTokenStoreSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi("client").provider(MapClientProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
.spi("group").provider(MapGroupProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||
|
|
Loading…
Reference in a new issue