CLI options to disable encryption and authentication to external Infinispan

Closes #28750

Signed-off-by: Pedro Ruivo <pruivo@redhat.com>
This commit is contained in:
Pedro Ruivo 2024-04-15 18:33:03 +01:00 committed by Alexander Schwartz
parent 6977d58d27
commit 3de5357091
8 changed files with 114 additions and 128 deletions

View file

@ -151,6 +151,16 @@ The configuration file is relative to the `conf/` directory.
For configuration of {project_name} server for high availability and multi-node clustered setup there was introduced following CLI options `cache-remote-host`, `cache-remote-port`, `cache-remote-username` and `cache-remote-password` simplifying configuration within the XML file. For configuration of {project_name} server for high availability and multi-node clustered setup there was introduced following CLI options `cache-remote-host`, `cache-remote-port`, `cache-remote-username` and `cache-remote-password` simplifying configuration within the XML file.
Once any of declared CLI parameters are present, it is expected there is no configuration related to remote store present in the XML file. Once any of declared CLI parameters are present, it is expected there is no configuration related to remote store present in the XML file.
==== Connecting to an insecure Infinispan server
WARNING: Disabling security is not recommended in production!
In development or test environment, it is easier to start an unsecured Infinispan server.
For these use case, the CLI options `cache-remote-tls-enabled` disables the encryption (SSL) between {project_name} and Infinispan.
{project_name} will fail to start if the Infinispan server is configured to accept only encrypted connections.
The CLI options `cache-remote-username` and `cache-remote-password` are optional and, if not set, {project_name} will connect to the Infinispan server without presenting any credentials.
If the Infinispan server has authentication enabled, {project_name} will fail to start.
== Transport stacks == Transport stacks
Transport stacks ensure that distributed cache nodes in a cluster communicate in a reliable fashion. Transport stacks ensure that distributed cache nodes in a cluster communicate in a reliable fashion.

View file

@ -186,7 +186,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
throw new RuntimeException("Multiple " + org.keycloak.cluster.ManagedCacheManagerProvider.class + " providers found."); throw new RuntimeException("Multiple " + org.keycloak.cluster.ManagedCacheManagerProvider.class + " providers found.");
} }
managedCacheManager = provider.getCacheManager(config); managedCacheManager = provider.getEmbeddedCacheManager(config);
} }
// store it in a locale variable first, so it is not visible to the outside, yet // store it in a locale variable first, so it is not visible to the outside, yet

View file

@ -21,6 +21,7 @@ public class CachingOptions {
public static final String CACHE_REMOTE_PORT_PROPERTY = CACHE_REMOTE_PREFIX + "-port"; public static final String CACHE_REMOTE_PORT_PROPERTY = CACHE_REMOTE_PREFIX + "-port";
public static final String CACHE_REMOTE_USERNAME_PROPERTY = CACHE_REMOTE_PREFIX + "-username"; public static final String CACHE_REMOTE_USERNAME_PROPERTY = CACHE_REMOTE_PREFIX + "-username";
public static final String CACHE_REMOTE_PASSWORD_PROPERTY = CACHE_REMOTE_PREFIX + "-password"; public static final String CACHE_REMOTE_PASSWORD_PROPERTY = CACHE_REMOTE_PREFIX + "-password";
public static final String CACHE_REMOTE_TLS_ENABLED_PROPERTY = CACHE_REMOTE_PREFIX + "-tls-enabled";
private static final String CACHE_METRICS_PREFIX = "cache-metrics"; private static final String CACHE_METRICS_PREFIX = "cache-metrics";
public static final String CACHE_METRICS_HISTOGRAMS_ENABLED_PROPERTY = CACHE_METRICS_PREFIX + "-histograms-enabled"; public static final String CACHE_METRICS_HISTOGRAMS_ENABLED_PROPERTY = CACHE_METRICS_PREFIX + "-histograms-enabled";
@ -44,7 +45,7 @@ public class CachingOptions {
kubernetes, kubernetes,
ec2, ec2,
azure, azure,
google; google
} }
public static final Option<Stack> CACHE_STACK = new OptionBuilder<>("cache-stack", Stack.class) public static final Option<Stack> CACHE_STACK = new OptionBuilder<>("cache-stack", Stack.class)
@ -126,4 +127,9 @@ public class CachingOptions {
.description("Enable histograms for metrics for the embedded caches.") .description("Enable histograms for metrics for the embedded caches.")
.build(); .build();
public static final Option<Boolean> CACHE_REMOTE_TLS_ENABLED = new OptionBuilder<>(CACHE_REMOTE_TLS_ENABLED_PROPERTY, Boolean.class)
.category(OptionCategory.CACHE)
.description("Enable SSL support to communication with a secure remote Infinispan server. It is not recommended to disable in production!")
.defaultValue(Boolean.TRUE)
.build();
} }

View file

@ -36,37 +36,32 @@ import io.quarkus.agroal.DataSource;
import io.quarkus.arc.Arc; import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle; import io.quarkus.arc.InstanceHandle;
import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener; import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.vertx.core.Handler; import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.RoutingContext;
import liquibase.Scope; import liquibase.Scope;
import liquibase.servicelocator.ServiceLocator;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.infinispan.commons.util.FileLookupFactory; import org.infinispan.commons.util.FileLookupFactory;
import org.infinispan.manager.DefaultCacheManager;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.crypto.CryptoIntegration; import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.crypto.CryptoProvider; import org.keycloak.common.crypto.CryptoProvider;
import org.keycloak.common.crypto.FipsMode; import org.keycloak.common.crypto.FipsMode;
import org.keycloak.config.MetricsOptions;
import org.keycloak.config.TruststoreOptions; import org.keycloak.config.TruststoreOptions;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider; import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory; import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator; import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
import org.keycloak.quarkus.runtime.storage.legacy.infinispan.CacheManagerFactory; import org.keycloak.quarkus.runtime.storage.legacy.infinispan.CacheManagerFactory;
import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.theme.ClasspathThemeProviderFactory; import org.keycloak.theme.ClasspathThemeProviderFactory;
import org.keycloak.truststore.TruststoreBuilder; import org.keycloak.truststore.TruststoreBuilder;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import liquibase.servicelocator.ServiceLocator;
import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory; import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getKcConfigValue; import static org.keycloak.quarkus.runtime.configuration.Configuration.getKcConfigValue;
@ -123,17 +118,8 @@ public class KeycloakRecorder {
public RuntimeValue<CacheManagerFactory> createCacheInitializer(ShutdownContext shutdownContext) { public RuntimeValue<CacheManagerFactory> createCacheInitializer(ShutdownContext shutdownContext) {
try { try {
boolean isMetricsEnabled = Configuration.isTrue(MetricsOptions.METRICS_ENABLED); CacheManagerFactory cacheManagerFactory = new CacheManagerFactory(getInfinispanConfigFile());
CacheManagerFactory cacheManagerFactory = new CacheManagerFactory(getInfinispanConfigFile(), isMetricsEnabled); shutdownContext.addShutdownTask(cacheManagerFactory::shutdown);
shutdownContext.addShutdownTask(() -> {
DefaultCacheManager cacheManager = cacheManagerFactory.getOrCreate();
if (cacheManager != null) {
cacheManager.stop();
}
});
return new RuntimeValue<>(cacheManagerFactory); return new RuntimeValue<>(cacheManagerFactory);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);

View file

@ -137,13 +137,7 @@ public final class Configuration {
} }
public static Optional<Boolean> getOptionalBooleanKcValue(String propertyName) { public static Optional<Boolean> getOptionalBooleanKcValue(String propertyName) {
Optional<String> value = getOptionalValue(NS_KEYCLOAK_PREFIX.concat(propertyName)); return getOptionalValue(NS_KEYCLOAK_PREFIX.concat(propertyName)).map(Boolean::parseBoolean);
if (value.isPresent()) {
return value.map(Boolean::parseBoolean);
}
return Optional.empty();
} }
public static Optional<Boolean> getOptionalBooleanValue(String name) { public static Optional<Boolean> getOptionalBooleanValue(String name) {

View file

@ -19,13 +19,15 @@ package org.keycloak.quarkus.runtime.storage.legacy.infinispan;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Metrics;
import org.infinispan.client.hotrod.impl.ConfigurationProperties; import org.infinispan.client.hotrod.impl.ConfigurationProperties;
import org.infinispan.commons.api.Lifecycle;
import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.PersistenceConfigurationBuilder; import org.infinispan.configuration.cache.PersistenceConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfiguration; import org.infinispan.configuration.global.GlobalConfiguration;
@ -43,16 +45,16 @@ import org.jgroups.protocols.UDP;
import org.jgroups.util.TLS; import org.jgroups.util.TLS;
import org.jgroups.util.TLSClientAuth; import org.jgroups.util.TLSClientAuth;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.config.CachingOptions;
import org.keycloak.config.MetricsOptions;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_ENABLED_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_KEYSTORE_FILE_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_KEYSTORE_FILE_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_KEYSTORE_PASSWORD_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_KEYSTORE_PASSWORD_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_TRUSTSTORE_FILE_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_TRUSTSTORE_FILE_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_TRUSTSTORE_PASSWORD_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_EMBEDDED_MTLS_TRUSTSTORE_PASSWORD_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_METRICS_HISTOGRAMS_ENABLED_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_REMOTE_HOST_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_REMOTE_HOST_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_REMOTE_PASSWORD_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_REMOTE_PASSWORD_PROPERTY;
import static org.keycloak.config.CachingOptions.CACHE_REMOTE_PORT_PROPERTY; import static org.keycloak.config.CachingOptions.CACHE_REMOTE_PORT_PROPERTY;
@ -68,44 +70,41 @@ public class CacheManagerFactory {
private static final Logger logger = Logger.getLogger(CacheManagerFactory.class); private static final Logger logger = Logger.getLogger(CacheManagerFactory.class);
private String config; private final String config;
private final boolean metricsEnabled; private final CompletableFuture<DefaultCacheManager> cacheManagerFuture;
private DefaultCacheManager cacheManager;
private Future<DefaultCacheManager> cacheManagerFuture;
private ExecutorService executor;
private boolean initialized;
public CacheManagerFactory(String config, boolean metricsEnabled) { public CacheManagerFactory(String config) {
this.config = config; this.config = config;
this.metricsEnabled = metricsEnabled; this.cacheManagerFuture = CompletableFuture.supplyAsync(this::startEmbeddedCacheManager);
this.executor = createThreadPool();
this.cacheManagerFuture = executor.submit(this::startCacheManager);
} }
public DefaultCacheManager getOrCreate() { public DefaultCacheManager getOrCreateEmbeddedCacheManager() {
if (cacheManager == null) { return join(cacheManagerFuture);
if (initialized) {
return null;
} }
public void shutdown() {
logger.debug("Shutdown embedded cache manager");
cacheManagerFuture.thenAccept(CacheManagerFactory::close);
}
private static <T> T join(Future<T> future) {
try { try {
// for now, we don't have any explicit property for setting the cache start timeout return future.get(getStartTimeout(), TimeUnit.SECONDS);
return cacheManager = cacheManagerFuture.get(getStartTimeout(), TimeUnit.SECONDS); } catch (InterruptedException e) {
} catch (Exception e) { Thread.currentThread().interrupt();
throw new RuntimeException("Failed to start caches", e); return null;
} finally { } catch (ExecutionException | TimeoutException e) {
shutdownThreadPool(); throw new RuntimeException("Failed to start embedded or remote cache manager", e);
} }
} }
return cacheManager; private static void close(Lifecycle lifecycle) {
if (lifecycle != null) {
lifecycle.stop();
}
} }
private ExecutorService createThreadPool() { private DefaultCacheManager startEmbeddedCacheManager() {
return Executors.newSingleThreadExecutor(r -> new Thread(r, "keycloak-cache-init"));
}
private DefaultCacheManager startCacheManager() {
ConfigurationBuilderHolder builder = new ParserRegistry().parse(config); ConfigurationBuilderHolder builder = new ParserRegistry().parse(config);
if (builder.getNamedConfigurationBuilders().entrySet().stream().anyMatch(c -> c.getValue().clustering().cacheMode().isClustered())) { if (builder.getNamedConfigurationBuilders().entrySet().stream().anyMatch(c -> c.getValue().clustering().cacheMode().isClustered())) {
@ -124,12 +123,12 @@ public class CacheManagerFactory {
} }
}); });
if (metricsEnabled) { if (Configuration.isTrue(MetricsOptions.METRICS_ENABLED)) {
builder.getGlobalConfigurationBuilder().addModule(MicrometerMeterRegisterConfigurationBuilder.class); builder.getGlobalConfigurationBuilder().addModule(MicrometerMeterRegisterConfigurationBuilder.class);
builder.getGlobalConfigurationBuilder().module(MicrometerMeterRegisterConfigurationBuilder.class).meterRegistry(Metrics.globalRegistry); builder.getGlobalConfigurationBuilder().module(MicrometerMeterRegisterConfigurationBuilder.class).meterRegistry(Metrics.globalRegistry);
builder.getGlobalConfigurationBuilder().cacheContainer().statistics(true); builder.getGlobalConfigurationBuilder().cacheContainer().statistics(true);
builder.getGlobalConfigurationBuilder().metrics().namesAsTags(true); builder.getGlobalConfigurationBuilder().metrics().namesAsTags(true);
if (booleanProperty(CACHE_METRICS_HISTOGRAMS_ENABLED_PROPERTY)) { if (Configuration.isTrue(CachingOptions.CACHE_METRICS_HISTOGRAMS_ENABLED)) {
builder.getGlobalConfigurationBuilder().metrics().histograms(true); builder.getGlobalConfigurationBuilder().metrics().histograms(true);
} }
builder.getNamedConfigurationBuilders().forEach((s, configurationBuilder) -> configurationBuilder.statistics().enabled(true)); builder.getNamedConfigurationBuilders().forEach((s, configurationBuilder) -> configurationBuilder.statistics().enabled(true));
@ -143,36 +142,35 @@ public class CacheManagerFactory {
return new DefaultCacheManager(builder, isStartEagerly()); return new DefaultCacheManager(builder, isStartEagerly());
} }
private boolean isStartEagerly() { private static boolean isRemoteTLSEnabled() {
return Configuration.isTrue(CachingOptions.CACHE_REMOTE_TLS_ENABLED);
}
private static boolean isRemoteAuthenticationEnabled() {
return Configuration.getOptionalValue(CACHE_REMOTE_USERNAME_PROPERTY).isPresent() ||
Configuration.getOptionalValue(CACHE_REMOTE_PASSWORD_PROPERTY).isEmpty();
}
private static SSLContext createSSLContext() {
try {
// uses the default Java Runtime TrustStore, or the one generated by Keycloak (see org.keycloak.truststore.TruststoreBuilder)
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
return sslContext;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new RuntimeException(e);
}
}
private static boolean isStartEagerly() {
// eagerly starts caches by default // eagerly starts caches by default
return Boolean.parseBoolean(System.getProperty("kc.cache-ispn-start-eagerly", Boolean.TRUE.toString())); return Boolean.parseBoolean(System.getProperty("kc.cache-ispn-start-eagerly", Boolean.TRUE.toString()));
} }
private Integer getStartTimeout() { private static int getStartTimeout() {
return Integer.getInteger("kc.cache-ispn-start-timeout", 120); return Integer.getInteger("kc.cache-ispn-start-timeout", 120);
} }
private void shutdownThreadPool() {
if (executor != null) {
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
Logger.getLogger(CacheManagerFactory.class).warn("Cache init thread pool not terminated");
}
}
} catch (Exception cause) {
executor.shutdownNow();
} finally {
executor = null;
cacheManagerFuture = null;
config = null;
initialized = true;
}
}
}
private void configureTransportStack(ConfigurationBuilderHolder builder) { private void configureTransportStack(ConfigurationBuilderHolder builder) {
String transportStack = Configuration.getRawValue("kc.cache-stack"); String transportStack = Configuration.getRawValue("kc.cache-stack");
@ -181,7 +179,7 @@ public class CacheManagerFactory {
transportConfig.defaultTransport().stack(transportStack); transportConfig.defaultTransport().stack(transportStack);
} }
if (booleanProperty(CACHE_EMBEDDED_MTLS_ENABLED_PROPERTY)) { if (Configuration.isTrue(CachingOptions.CACHE_REMOTE_TLS_ENABLED)) {
validateTlsAvailable(transportConfig.build()); validateTlsAvailable(transportConfig.build());
var tls = new TLS() var tls = new TLS()
.enabled(true) .enabled(true)
@ -218,25 +216,14 @@ public class CacheManagerFactory {
private void configureRemoteStores(ConfigurationBuilderHolder builder) { private void configureRemoteStores(ConfigurationBuilderHolder builder) {
//if one of remote store command line parameters is defined, some other are required, otherwise assume it'd configured via xml only //if one of remote store command line parameters is defined, some other are required, otherwise assume it'd configured via xml only
if (Configuration.getOptionalKcValue(CACHE_REMOTE_HOST_PROPERTY).isPresent() || if (Configuration.getOptionalKcValue(CACHE_REMOTE_HOST_PROPERTY).isPresent()) {
Configuration.getOptionalKcValue(CACHE_REMOTE_USERNAME_PROPERTY).isPresent() ||
Configuration.getOptionalKcValue(CACHE_REMOTE_PASSWORD_PROPERTY).isPresent()) {
String cacheRemoteHost = requiredStringProperty(CACHE_REMOTE_HOST_PROPERTY); String cacheRemoteHost = requiredStringProperty(CACHE_REMOTE_HOST_PROPERTY);
Integer cacheRemotePort = Configuration.getOptionalKcValue(CACHE_REMOTE_PORT_PROPERTY) Integer cacheRemotePort = Configuration.getOptionalKcValue(CACHE_REMOTE_PORT_PROPERTY)
.map(Integer::parseInt) .map(Integer::parseInt)
.orElse(ConfigurationProperties.DEFAULT_HOTROD_PORT); .orElse(ConfigurationProperties.DEFAULT_HOTROD_PORT);
String cacheRemoteUsername = requiredStringProperty(CACHE_REMOTE_USERNAME_PROPERTY);
String cacheRemotePassword = requiredStringProperty(CACHE_REMOTE_PASSWORD_PROPERTY);
SSLContext sslContext; SSLContext sslContext = createSSLContext();
try {
// uses the default Java Runtime TrustStore, or the one generated by Keycloak (see org.keycloak.truststore.TruststoreBuilder)
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new RuntimeException(e);
}
DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> { DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> {
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE) && if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE) &&
@ -251,7 +238,8 @@ public class CacheManagerFactory {
throw new RuntimeException(String.format("Remote store for cache '%s' is already configured via CLI parameters. It should not be present in the XML file.", cacheName)); throw new RuntimeException(String.format("Remote store for cache '%s' is already configured via CLI parameters. It should not be present in the XML file.", cacheName));
} }
persistenceCB.addStore(RemoteStoreConfigurationBuilder.class) var storeBuilder = persistenceCB.addStore(RemoteStoreConfigurationBuilder.class);
storeBuilder
.rawValues(true) .rawValues(true)
.shared(true) .shared(true)
.segmented(false) .segmented(false)
@ -259,26 +247,29 @@ public class CacheManagerFactory {
.connectionPool() .connectionPool()
.maxActive(16) .maxActive(16)
.exhaustedAction(ExhaustedAction.CREATE_NEW) .exhaustedAction(ExhaustedAction.CREATE_NEW)
.remoteSecurity()
.ssl()
.enable()
.sslContext(sslContext)
.sniHostName(cacheRemoteHost)
.authentication()
.enable()
.username(cacheRemoteUsername)
.password(cacheRemotePassword)
.realm("default")
.saslMechanism(SCRAM_SHA_512)
.addServer() .addServer()
.host(cacheRemoteHost) .host(cacheRemoteHost)
.port(cacheRemotePort); .port(cacheRemotePort);
});
} if (isRemoteTLSEnabled()) {
storeBuilder.remoteSecurity()
.ssl()
.enable()
.sslContext(sslContext)
.sniHostName(cacheRemoteHost);
} }
private static boolean booleanProperty(String propertyName) { if (isRemoteAuthenticationEnabled()) {
return Configuration.getOptionalKcValue(propertyName).map(Boolean::parseBoolean).orElse(Boolean.FALSE); storeBuilder.remoteSecurity()
.authentication()
.enable()
.username(requiredStringProperty(CACHE_REMOTE_USERNAME_PROPERTY))
.password(requiredStringProperty(CACHE_REMOTE_PASSWORD_PROPERTY))
.realm("default")
.saslMechanism(SCRAM_SHA_512);
}
});
}
} }
private static String requiredStringProperty(String propertyName) { private static String requiredStringProperty(String propertyName) {

View file

@ -17,10 +17,9 @@
package org.keycloak.quarkus.runtime.storage.legacy.infinispan; package org.keycloak.quarkus.runtime.storage.legacy.infinispan;
import org.keycloak.cluster.ManagedCacheManagerProvider;
import org.keycloak.Config;
import io.quarkus.arc.Arc; import io.quarkus.arc.Arc;
import org.keycloak.Config;
import org.keycloak.cluster.ManagedCacheManagerProvider;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -28,7 +27,7 @@ import io.quarkus.arc.Arc;
public final class QuarkusCacheManagerProvider implements ManagedCacheManagerProvider { public final class QuarkusCacheManagerProvider implements ManagedCacheManagerProvider {
@Override @Override
public <C> C getCacheManager(Config.Scope config) { public <C> C getEmbeddedCacheManager(Config.Scope config) {
return (C) Arc.container().instance(CacheManagerFactory.class).get().getOrCreate(); return (C) Arc.container().instance(CacheManagerFactory.class).get().getOrCreateEmbeddedCacheManager();
} }
} }

View file

@ -20,11 +20,11 @@ package org.keycloak.cluster;
import org.keycloak.Config; import org.keycloak.Config;
/** /**
* A Service Provider Interface (SPI) that allows to plug-in a cache manager instance. * A Service Provider Interface (SPI) that allows to plug-in an embedded cache manager instance.
* *
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
public interface ManagedCacheManagerProvider { public interface ManagedCacheManagerProvider {
<C> C getCacheManager(Config.Scope config); <C> C getEmbeddedCacheManager(Config.Scope config);
} }