Introduce CLI parameter to set the deployment state version seed

Closes #12710
This commit is contained in:
Alexander Schwartz 2022-07-25 12:36:01 +02:00 committed by Hynek Mlnařík
parent 650f3a8367
commit 8470a30446
9 changed files with 62 additions and 10 deletions

View file

@ -50,13 +50,13 @@ public class MapDeploymentStateProviderFactory implements DeploymentStateProvide
String seed = config.get(RESOURCES_VERSION_SEED);
if (seed == null) {
Logger.getLogger(DeploymentStateProviderFactory.class)
.warnf("It is recommended to set '%s' property in the %s provider config of %s SPI", RESOURCES_VERSION_SEED, PROVIDER_ID, DeploymentStateSpi.NAME);
.warnf("Version seed for deployment state set with a random number. Caution: This can lead to unstable operations when serving resources from the cluster without a sticky loadbalancer or when restarting nodes. Set the '%s' property in the %s provider config of %s SPI for stable operations", RESOURCES_VERSION_SEED, PROVIDER_ID, DeploymentStateSpi.NAME);
//generate random string for this installation
seed = SecretGenerator.getInstance().randomString(10);
}
try {
Version.RESOURCES_VERSION = Base64Url.encode(MessageDigest.getInstance("SHA-256")
.digest((seed + new ModelVersion(Version.VERSION_KEYCLOAK).toString()).getBytes()))
.digest((seed + Version.RESOURCES_VERSION).getBytes()))
.substring(0, 5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);

View file

@ -167,6 +167,13 @@ public class StorageOptions {
.buildTime(true)
.build();
public static final Option<String> STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED = new OptionBuilder<>("storage-deployment-state-version-seed", String.class)
.category(OptionCategory.STORAGE)
.description("Secret that serves as a seed to mask the version number of Keycloak in URLs. Need to be identical across all servers in the cluster. Will default to a random number generated when starting the server which is secure but will lead to problems when a loadbalancer without sticky sessions is used or nodes are restarted.")
.hidden()
.buildTime(false)
.build();
public static final Option<String> STORAGE_AUTH_SESSION_PROVIDER = new OptionBuilder<>("storage-auth-session-provider", String.class)
.category(OptionCategory.STORAGE)
.hidden()

View file

@ -21,6 +21,9 @@ import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
import org.jboss.logging.Logger;
import org.keycloak.common.util.SecretGenerator;
import org.keycloak.config.StorageOptions;
import org.keycloak.config.StorageOptions.StorageType;
@ -136,6 +139,11 @@ final class StoragePropertyMappers {
.transformer(StoragePropertyMappers::getAreaStorage)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED)
.to("kc.spi-deployment-state-map-resources-version-seed")
.transformer(StoragePropertyMappers::getResourcesVersionSeed)
.paramLabel("type")
.build(),
fromOption(StorageOptions.STORAGE_AUTH_SESSION_PROVIDER)
.to("kc.spi-authentication-sessions-provider")
.mapFrom("storage")
@ -307,18 +315,19 @@ final class StoragePropertyMappers {
};
}
private static Optional<String> isForceComponentFactoryCache(Optional<String> storage, ConfigSourceInterceptorContext context) {
if (storage.isPresent()) {
return Optional.of(Boolean.TRUE.toString());
}
return storage;
}
private static Optional<String> getAreaStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? "jpa" : "map");
}
private static Optional<String> getResourcesVersionSeed(Optional<String> parameterValue, ConfigSourceInterceptorContext context) {
if (!parameterValue.isEmpty()) {
return parameterValue;
}
Logger.getLogger(StoragePropertyMappers.class)
.warnf("Version seed for deployment state set with a random number. Caution: This can lead to unstable operations when serving resources from the cluster without a sticky loadbalancer or when restarting nodes. Set the '--%s' option with a secret seed to ensure stable operations.", StorageOptions.STORAGE_DEPLOYMENT_STATE_RESOURCES_VERSION_SEED.getKey());
return Optional.of(SecretGenerator.getInstance().randomString(10));
}
private static Optional<String> getCacheStorage(Optional<String> storage, ConfigSourceInterceptorContext context) {
return of(storage.isEmpty() ? "infinispan" : "map");
}

View file

@ -73,6 +73,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.

View file

@ -73,6 +73,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.

View file

@ -79,6 +79,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.

View file

@ -79,6 +79,12 @@ Storage (Experimental):
--storage-area-user-session <type>
Experimental: Sets a storage mechanism for user and client sessions. Possible
values are: jpa, chm, hotrod.
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.

View file

@ -22,6 +22,12 @@ Options:
Storage (Experimental):
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.

View file

@ -22,6 +22,12 @@ Options:
Storage (Experimental):
--storage-deployment-state-version-seed <type>
Experimental: Secret that serves as a seed to mask the version number of
Keycloak in URLs. Need to be identical across all servers in the cluster.
Will default to a random number generated when starting the server which is
secure but will lead to problems when a loadbalancer without sticky sessions
is used or nodes are restarted.
--storage-hotrod-cache-configure <true|false>
Experimental: When set to true, Keycloak will create and configure Infinispan
caches on startup. Default: true.