diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/RemoteCacheProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/RemoteCacheProvider.java
index ea1ba9f..055e89b 100644
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/RemoteCacheProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/RemoteCacheProvider.java
@@ -20,7 +20,6 @@ package org.keycloak.connections.infinispan;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -40,6 +39,8 @@ import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.common.util.reflections.Reflections;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
+import java.util.stream.Collectors;
+import org.infinispan.client.hotrod.exceptions.HotRodClientException;
/**
* Get either just remoteCache associated with remoteStore associated with infinispan cache of given name. If security is enabled, then
@@ -52,6 +53,8 @@ import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
*/
public class RemoteCacheProvider {
+ public static final String SCRIPT_CACHE_NAME = "___script_cache";
+
protected static final Logger logger = Logger.getLogger(RemoteCacheProvider.class);
private final Config.Scope config;
@@ -60,7 +63,7 @@ public class RemoteCacheProvider {
private final Map<String, RemoteCache> availableCaches = new HashMap<>();
// Enlist secured managers, which are managed by us and should be shutdown on stop
- private final List<RemoteCacheManager> managedManagers = new LinkedList<>();
+ private final Map<String, RemoteCacheManager> managedManagers = new HashMap<>();
public RemoteCacheProvider(Config.Scope config, EmbeddedCacheManager cacheManager) {
this.config = config;
@@ -81,42 +84,51 @@ public class RemoteCacheProvider {
}
public void stop() {
- // TODO:mposolda
- logger.infof("Shutdown %d registered secured remoteCache managers", managedManagers.size());
+ logger.debugf("Shutdown %d registered secured remoteCache managers", managedManagers.size());
- for (RemoteCacheManager mgr : managedManagers) {
+ for (RemoteCacheManager mgr : managedManagers.values()) {
mgr.stop();
}
}
- protected RemoteCache loadRemoteCache(String cacheName) {
+ protected synchronized RemoteCache loadRemoteCache(String cacheName) {
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cacheManager.getCache(cacheName));
- if (config.getBoolean("remoteStoreSecurityEnabled", false)) {
- // TODO:mposolda
- logger.info("Remote store security is enabled");
- RemoteCacheManager securedMgr = createSecuredRemoteCacheManager(config, remoteCache.getRemoteCacheManager());
- managedManagers.add(securedMgr);
+ Boolean remoteStoreSecurity = config.getBoolean("remoteStoreSecurityEnabled");
+ if (remoteStoreSecurity == null) {
+ try {
+ logger.debugf("Detecting remote security settings of HotRod server, cache %s. Disable by explicitly setting \"remoteStoreSecurityEnabled\" property in spi=connectionsInfinispan/provider=default", cacheName);
+ remoteStoreSecurity = false;
+ final RemoteCache<Object, Object> scriptCache = remoteCache.getRemoteCacheManager().getCache(SCRIPT_CACHE_NAME);
+ if (scriptCache == null) {
+ logger.debug("Cannot detect remote security settings of HotRod server, disabling.");
+ } else {
+ scriptCache.containsKey("");
+ }
+ } catch (HotRodClientException ex) {
+ logger.debug("Seems that HotRod server requires authentication, enabling.");
+ remoteStoreSecurity = true;
+ }
+ }
+
+ if (remoteStoreSecurity) {
+ logger.infof("Remote store security for cache %s is enabled. Disable by setting \"remoteStoreSecurityEnabled\" property to \"false\" in spi=connectionsInfinispan/provider=default", cacheName);
+ RemoteCacheManager securedMgr = getOrCreateSecuredRemoteCacheManager(config, cacheName, remoteCache.getRemoteCacheManager());
return securedMgr.getCache(remoteCache.getName());
} else {
- // TODO:mposolda
- logger.info("Remote store security is disabled");
+ logger.infof("Remote store security for cache %s is disabled. If server fails to connect to remote JDG server, enable it.", cacheName);
return remoteCache;
}
}
- protected RemoteCacheManager createSecuredRemoteCacheManager(Config.Scope config, RemoteCacheManager origManager) {
- String serverName = config.get("remoteStoreSecurityServerName", "keycloak-server");
- String realm = config.get("remoteStoreSecurityRealm", "ApplicationRealm");
+ protected RemoteCacheManager getOrCreateSecuredRemoteCacheManager(Config.Scope config, String cacheName, RemoteCacheManager origManager) {
+ String serverName = config.get("remoteStoreSecurityServerName", "keycloak-jdg-server");
+ String realm = config.get("remoteStoreSecurityRealm", "AllowScriptManager");
- String securedHotRodEndpoint = config.get("remoteStoreSecurityHotRodEndpoint");
- String username = config.get("remoteStoreSecurityUsername");
- String password = config.get("remoteStoreSecurityPassword");
-
- // TODO:mposolda
- logger.infof("Server: '%s', Realm: '%s', Username: '%s', Secured HotRod endpoint: '%s'", serverName, realm, username, securedHotRodEndpoint);
+ String username = config.get("remoteStoreSecurityUsername", "___script_manager");
+ String password = config.get("remoteStoreSecurityPassword", "not-so-secret-password");
// Create configuration template from the original configuration provided at remoteStore level
Configuration origConfig = origManager.getConfiguration();
@@ -124,6 +136,16 @@ public class RemoteCacheProvider {
ConfigurationBuilder cfgBuilder = new ConfigurationBuilder()
.read(origConfig);
+ String securedHotRodEndpoint = origConfig.servers().stream()
+ .map(serverConfiguration -> serverConfiguration.host() + ":" + serverConfiguration.port())
+ .collect(Collectors.joining(";"));
+
+ if (managedManagers.containsKey(securedHotRodEndpoint)) {
+ return managedManagers.get(securedHotRodEndpoint);
+ }
+
+ logger.infof("Creating secured RemoteCacheManager for Server: '%s', Cache: '%s', Realm: '%s', Username: '%s', Secured HotRod endpoint: '%s'", serverName, cacheName, realm, username, securedHotRodEndpoint);
+
// Workaround as I need a way to override servers and it's not possible to remove existing :/
try {
Field serversField = cfgBuilder.getClass().getDeclaredField("servers");
@@ -145,7 +167,9 @@ public class RemoteCacheProvider {
.enable()
.build();
- return new RemoteCacheManager(newConfig);
+ final RemoteCacheManager remoteCacheManager = new RemoteCacheManager(newConfig);
+ managedManagers.put(securedHotRodEndpoint, remoteCacheManager);
+ return remoteCacheManager;
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
index ba13171..53b294c 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
@@ -27,6 +27,7 @@ import org.infinispan.commons.marshall.Marshaller;
import org.infinispan.context.Flag;
import org.jboss.logging.Logger;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
+import org.keycloak.connections.infinispan.RemoteCacheProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.initializer.BaseCacheInitializer;
@@ -88,7 +89,7 @@ public class RemoteCacheSessionsLoader implements SessionLoader {
public void init(KeycloakSession session) {
RemoteCache remoteCache = getRemoteCache(session);
- RemoteCache<String, String> scriptCache = remoteCache.getRemoteCacheManager().getCache("___script_cache");
+ RemoteCache<String, String> scriptCache = remoteCache.getRemoteCacheManager().getCache(RemoteCacheProvider.SCRIPT_CACHE_NAME);
if (!scriptCache.containsKey("load-sessions.js")) {
scriptCache.put("load-sessions.js",