KEYCLOAK-6783 JDG-auth optimizations
This commit is contained in:
parent
6f7200868b
commit
05dcc6e3af
2 changed files with 49 additions and 24 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue