From c93aa380492d97d0be2347d3229420d3ed933f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BChle?= Date: Tue, 13 Aug 2024 01:38:15 +0200 Subject: [PATCH 1/5] Add Info Logs for Store Client Setup --- ...yProcessPluginDeploymentStateListener.java | 13 +++++---- .../FlareWebserviceClientSpringConfig.java | 13 +++++++++ .../client/store/StoreClientSpringConfig.java | 29 +++++++++++++++++-- ...cessPluginDeploymentStateListenerTest.java | 12 ++++---- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListener.java b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListener.java index 16e0a02..ec5ccf0 100644 --- a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListener.java +++ b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListener.java @@ -44,18 +44,19 @@ public void onProcessesDeployed(List processes) { try { var statement = storeClient.capabilities().ofType(CapabilityStatement.class) .execute(); - logger.info("Connection test OK ({} - {})", statement.getSoftware().getName(), - statement.getSoftware().getVersion()); + logger.info("Feasibility plugin connection test to FHIR store ({} - {}) SUCCEEDED.", + statement.getSoftware().getName(), statement.getSoftware().getVersion()); } catch (Exception e) { - logger.error("Connection test FAILED - error: {} - {}", e.getClass().getName(), e.getMessage()); + logger.error("Feasibility plugin connection test to FHIR store FAILED. Error: {} - {}", + e.getClass().getName(), e.getMessage()); } } else { try { flareWebserviceClient.testConnection(); - logger.info("Connection test OK (flare)"); + logger.info("Feasibility plugin connection test to flare SUCCEEDED."); } catch (Exception e) { - logger.error("Connection test FAILED (flare) - error: {} - {}", e.getClass().getName(), - e.getMessage()); + logger.error("Feasibility plugin connection test to flare FAILED. Error: {} - {}", + e.getClass().getName(), e.getMessage()); } } } diff --git a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientSpringConfig.java b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientSpringConfig.java index f964eac..b8b1a60 100644 --- a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientSpringConfig.java +++ b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientSpringConfig.java @@ -22,6 +22,8 @@ import org.apache.http.message.BasicHeader; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -44,6 +46,8 @@ @Import({ BaseConfig.class, EvaluationConfig.class }) public class FlareWebserviceClientSpringConfig { + private static final Logger logger = LoggerFactory.getLogger(FlareWebserviceClientSpringConfig.class); + @Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.flare.base_url:}") private String flareBaseUrl; @@ -100,6 +104,9 @@ private FlareWebserviceClient createFlareClient(HttpClient httpClient) { public HttpClient flareHttpClient(@Qualifier("base-client") SSLContext sslContext, EvaluationSettingsProvider evaluationSettingsProvider) { if (EvaluationStrategy.STRUCTURED_QUERY == evaluationSettingsProvider.evaluationStrategy()) { + logger.info("Setting up store client for indirect access over flare using {}.", + EvaluationStrategy.STRUCTURED_QUERY); + var clientFactory = new TlsClientFactory(null, sslContext); clientFactory.setConnectTimeout(connectTimeout); clientFactory.setConnectionRequestTimeout(connectTimeout); @@ -111,17 +118,23 @@ public HttpClient flareHttpClient(@Qualifier("base-client") SSLContext sslContex if (!isNullOrEmpty(proxyHost) && proxyPort != null) { var proxy = new HttpHost(proxyHost, proxyPort); builder.setProxy(proxy); + logger.info("Setting proxy (host: '{}', port: '{}') for store client.", proxyHost, proxyPort); if (!isNullOrEmpty(proxyUsername) && !isNullOrEmpty(proxyPassword)) { + logger.info("Setting proxy credentials (username: '{}', password: '***') for store client.", + proxyUsername); builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials(proxyUsername, proxyPassword)); } } if (!isNullOrEmpty(basicAuthUsername) && !isNullOrEmpty(basicAuthPassword)) { + logger.info("Setting basic authentication (username: '{}', password: '***') for store client.", + basicAuthUsername); var flareUri = URI.create(flareBaseUrl); credentialsProvider.setCredentials(new AuthScope(new HttpHost(flareUri.getHost(), flareUri.getPort())), new UsernamePasswordCredentials(basicAuthUsername, basicAuthPassword)); } else if (!isNullOrEmpty(bearerAuthToken)) { + logger.info("Setting bearer token '***' for store client."); return new BearerHttpClient(builder.setDefaultCredentialsProvider(credentialsProvider).build()); } return builder.setDefaultCredentialsProvider(credentialsProvider).build(); diff --git a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java index 3f2cb1d..b6a0240 100644 --- a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java +++ b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java @@ -6,7 +6,10 @@ import ca.uhn.fhir.rest.client.impl.RestfulClientFactory; import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor; import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor; +import de.medizininformatik_initiative.process.feasibility.EvaluationStrategy; import de.medizininformatik_initiative.process.feasibility.spring.config.BaseConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -19,11 +22,14 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static de.medizininformatik_initiative.process.feasibility.variables.ConstantsFeasibility.CLIENT_TIMEOUT_DEFAULT; +import static java.util.Objects.nonNull; @Configuration @Import(BaseConfig.class) public class StoreClientSpringConfig { + private static final Logger logger = LoggerFactory.getLogger(StoreClientSpringConfig.class); + @Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.proxy.host:#{null}}") private String proxyHost; @@ -64,7 +70,7 @@ public class StoreClientSpringConfig { private String oauthClientId; @Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.auth.oauth.issuer.url:#{null}}") - private String oauthTokenUrl; + private String oauthIssuerUrl; @Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.auth.oauth.proxy.host:#{null}}") private String oauthProxyHost; @@ -82,30 +88,47 @@ public class StoreClientSpringConfig { @Qualifier("store-client") IGenericClient client(@Qualifier("store-client") FhirContext fhirContext, @Qualifier("store-client") RestfulClientFactory clientFactory) { + logger.info("Setting up store client for direct access using {}.", + EvaluationStrategy.CQL); + clientFactory.setServerValidationMode(ServerValidationModeEnum.NEVER); clientFactory.setConnectTimeout(connectTimeout); clientFactory.setConnectionRequestTimeout(connectRequestTimeout); clientFactory.setSocketTimeout(socketTimeout); if (proxyHost != null) { + logger.info("Setting proxy (host: '{}', port: '{}') for store client.", proxyHost, proxyPort); clientFactory.setProxy(proxyHost, proxyPort); if (proxyUsername != null || proxyPassword != null) { + logger.info("Setting proxy credentials (username: '{}', password: '***') for store client.", + proxyUsername); clientFactory.setProxyCredentials(proxyUsername, proxyPassword); } } fhirContext.setRestfulClientFactory(clientFactory); var client = fhirContext.newRestfulGenericClient(storeBaseUrl); if (bearerAuthToken != null) { + logger.info("Setting bearer token '***' for store client."); client.registerInterceptor(new BearerTokenAuthInterceptor(bearerAuthToken)); } else if (!isNullOrEmpty(oauthClientId) && !isNullOrEmpty(oauthClientSecret) - && !isNullOrEmpty(oauthTokenUrl)) { - client.registerInterceptor(new OAuthInterceptor(oauthClientId, oauthClientSecret, oauthTokenUrl, + && !isNullOrEmpty(oauthIssuerUrl)) { + logger.info("Setting OAuth2.0 authentication (issuer url: '{}', client id: '{}', password: '***')" + + " for store client.", oauthIssuerUrl, oauthClientId); + if (nonNull(oauthProxyHost) && nonNull(oauthProxyPort)) { + logger.info("Setting proxy (host: '{}', port: '{}', username: {}," + + " password {}) for OAuth2.0 authentication.", oauthProxyHost, oauthProxyPassword, + Optional.ofNullable(oauthProxyUsername).map(u -> "'" + u + "'").orElse("none"), + Optional.ofNullable(oauthProxyPassword).map(p -> "'***'").orElse("none")); + } + client.registerInterceptor(new OAuthInterceptor(oauthClientId, oauthClientSecret, oauthIssuerUrl, Optional.ofNullable(oauthProxyHost), Optional.ofNullable(oauthProxyPort), Optional.ofNullable(oauthProxyUsername), Optional.ofNullable(oauthProxyPassword))); } if (basicAuthUsername != null || basicAuthPassword != null) { + logger.info("Setting basic authentication (username: '{}', password: '***') for store client.", + basicAuthUsername); client.registerInterceptor(new BasicAuthInterceptor(basicAuthUsername, basicAuthPassword)); } diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListenerTest.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListenerTest.java index 8fb13d7..bd5be11 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListenerTest.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/FeasibilityProcessPluginDeploymentStateListenerTest.java @@ -86,7 +86,7 @@ void flareClientConnectionTestSucceeds() throws Exception { listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID)); verify(flareClient).testConnection(); - assertThat(out.toString(), containsString("Connection test OK (flare)")); + assertThat(out.toString(), containsString("Feasibility plugin connection test to flare SUCCEEDED.")); } @Test @@ -107,7 +107,8 @@ void storeClientConnectionTestSucceeds() throws Exception { listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID)); assertThat(out.toString(), - containsString(format("Connection test OK (%s - %s)", softwareName, softwareVersion))); + containsString(format("Feasibility plugin connection test to FHIR store (%s - %s) SUCCEEDED.", + softwareName, softwareVersion))); } @Test @@ -121,7 +122,8 @@ void flareClientConnectionTestFails() throws Exception { listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID)); - assertThat(out.toString(), containsString(format("Connection test FAILED (flare) - error: %s - %s", + assertThat(out.toString(), + containsString(format("Feasibility plugin connection test to flare FAILED. Error: %s - %s", exception.getClass().getName(), errorMessage))); } @@ -139,8 +141,8 @@ void storeClientConnectionTestFails() throws Exception { listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID)); assertThat(out.toString(), - containsString(format("Connection test FAILED - error: %s - %s", exception.getClass().getName(), - errorMessage))); + containsString(format("Feasibility plugin connection test to FHIR store FAILED. Error: %s - %s", + exception.getClass().getName(), errorMessage))); } } From 9d2452a78af3b1ddbdc3142afd056c17fa415ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BChle?= Date: Wed, 11 Sep 2024 10:52:27 +0200 Subject: [PATCH 2/5] Use SSL Context for OpenID Connect Provider Metadata Retrieval --- .../proxy}/nginx.conf | 0 .../rebuild.sh | 9 ++- .../client/store/OAuthInterceptor.java | 32 ++++++-- .../client/store/StoreClientSpringConfig.java | 6 +- .../client/store/OAuthInterceptorIT.java | 81 ++++++++++++++++--- ...proxy.conf => keycloak_forward_proxy.conf} | 0 ...passwd => keycloak_forward_proxy.htpasswd} | 0 ...=> keycloak_forward_proxy_basic_auth.conf} | 0 .../keycloak_reverse_proxy.conf.template | 25 ++++++ .../feasibility/client/store/nginx.conf | 30 +++++++ 10 files changed, 160 insertions(+), 23 deletions(-) rename mii-process-feasibility-docker-test-setup/{dic-3-store-proxy => dic-3/proxy}/nginx.conf (100%) rename mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/{forward_proxy.conf => keycloak_forward_proxy.conf} (100%) rename mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/{forward_proxy.htpasswd => keycloak_forward_proxy.htpasswd} (100%) rename mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/{forward_proxy_basic_auth.conf => keycloak_forward_proxy_basic_auth.conf} (100%) create mode 100644 mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_reverse_proxy.conf.template diff --git a/mii-process-feasibility-docker-test-setup/dic-3-store-proxy/nginx.conf b/mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf similarity index 100% rename from mii-process-feasibility-docker-test-setup/dic-3-store-proxy/nginx.conf rename to mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf diff --git a/mii-process-feasibility-docker-test-setup/rebuild.sh b/mii-process-feasibility-docker-test-setup/rebuild.sh index 562382e..1668282 100755 --- a/mii-process-feasibility-docker-test-setup/rebuild.sh +++ b/mii-process-feasibility-docker-test-setup/rebuild.sh @@ -3,8 +3,8 @@ set -e BASE_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -mvn -f ../mii-process-feasibility/pom.xml clean package -mvn -f ../mii-process-feasibility-tools/mii-process-feasibility-test-data-generator/pom.xml clean package +mvn -f "${BASE_DIR}/../mii-process-feasibility/pom.xml" clean package +mvn -f "${BASE_DIR}/../mii-process-feasibility-tools/mii-process-feasibility-test-data-generator/pom.xml" clean package # Create a self signed CA openssl req -x509 -sha256 -days 365 -nodes -newkey rsa:2048 -keyout ${BASE_DIR}/secrets/dic_3_store_proxy_self_signed_ca_key.pem \ @@ -29,12 +29,15 @@ keytool -importcert -file ${BASE_DIR}/secrets/dic_3_store_proxy_self_signed_ca.p # Issue certificate using said self signed CA openssl req -nodes -sha256 -new -newkey rsa:2048 -keyout ${BASE_DIR}/secrets/dic_3_store_proxy_cert_key.pem \ -out ${BASE_DIR}/secrets/dic_3_store_proxy_cert_csr.pem \ - -subj "/C=DE/ST=Berlin/L=Berlin/O=Bar/CN=dic-3-store-proxy" + -subj "/C=DE/ST=Berlin/L=Berlin/O=Bar/CN=dic-3-store-proxy" \ + -addext "basicConstraints=CA:false" \ + -addext "subjectAltName = DNS:dic-3-store-proxy, DNS:dic-3-keycloak-proxy" openssl x509 -req -days 365 -sha256 -in ${BASE_DIR}/secrets/dic_3_store_proxy_cert_csr.pem \ -CA ${BASE_DIR}/secrets/dic_3_store_proxy_self_signed_ca.pem \ -CAkey ${BASE_DIR}/secrets/dic_3_store_proxy_self_signed_ca_key.pem \ -CAcreateserial \ + -copy_extensions=copyall \ -out ${BASE_DIR}/secrets/dic_3_store_proxy_cert.pem rm -f ${BASE_DIR}/secrets/dic_3_store_proxy_self_signed_ca.srl diff --git a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptor.java b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptor.java index 5f354f8..4daa78d 100644 --- a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptor.java +++ b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptor.java @@ -16,6 +16,7 @@ import com.nimbusds.oauth2.sdk.id.ClientID; import com.nimbusds.oauth2.sdk.id.Issuer; import com.nimbusds.oauth2.sdk.token.AccessToken; +import com.nimbusds.oauth2.sdk.util.tls.TLSUtils; import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata; import org.joda.time.DateTime; @@ -24,6 +25,11 @@ import java.net.Proxy; import java.net.Proxy.Type; import java.net.URI; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.util.Base64; import java.util.Optional; @@ -38,11 +44,13 @@ final class OAuthInterceptor implements IClientInterceptor { private Optional proxyAuthHeader; private Issuer issuer; private ClientSecretBasic clientAuth; + private KeyStore trustStore; public OAuthInterceptor(String oauthClientId, String oauthClientSecret, String oauthIssuerUrl, - Optional proxyHost, Optional proxyPort, Optional proxyUsername, - Optional proxyPassword) { + KeyStore trustStore, Optional proxyHost, Optional proxyPort, + Optional proxyUsername, Optional proxyPassword) { super(); + this.trustStore = trustStore; clientAuth = new ClientSecretBasic(new ClientID(oauthClientId), new Secret(oauthClientSecret)); issuer = new Issuer(oauthIssuerUrl); proxy = proxyHost.map( @@ -71,24 +79,34 @@ public String getToken() { token = successResponse.getTokens().getAccessToken(); tokenExpiry = DateTime.now().plus(token.getLifetime() * 1000); - } catch (GeneralException | IOException e) { - throw new OAuth2ClientException("OAuth2 access token tokenRequest failed", e); + } catch (Exception e) { + throw new OAuth2ClientException("Requesting OAuth2 access token failed: " + e.getMessage(), e); } } return token.getValue(); } - private HTTPRequest getTokenRequest() throws GeneralException, IOException { + private HTTPRequest getTokenRequest() throws GeneralException, IOException, KeyManagementException, + UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException { if (tokenRequest == null) { HTTPRequest request = new TokenRequest(getTokenUri(), clientAuth, new ClientCredentialsGrant()) .toHTTPRequest(); - tokenRequest = setProxy(request); + tokenRequest = setProxy(setSSLSocketFactory(request)); } return tokenRequest; } private URI getTokenUri() throws GeneralException, IOException { - return OIDCProviderMetadata.resolve(issuer, r -> { setProxy(r); }).getTokenEndpointURI(); + return OIDCProviderMetadata.resolve(issuer, r -> setProxy(setSSLSocketFactory(r))).getTokenEndpointURI(); + } + + private HTTPRequest setSSLSocketFactory(HTTPRequest request) { + try { + request.setSSLSocketFactory(TLSUtils.createSSLSocketFactory(trustStore)); + } catch (KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException e) { + throw new IllegalArgumentException("Could not configure TLS with given trust store.", e); + } + return request; } private HTTPRequest setProxy(HTTPRequest request) { diff --git a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java index b6a0240..541f991 100644 --- a/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java +++ b/mii-process-feasibility/src/main/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientSpringConfig.java @@ -16,6 +16,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import java.security.KeyStore; import java.util.Optional; import javax.net.ssl.SSLContext; @@ -87,7 +88,8 @@ public class StoreClientSpringConfig { @Bean @Qualifier("store-client") IGenericClient client(@Qualifier("store-client") FhirContext fhirContext, - @Qualifier("store-client") RestfulClientFactory clientFactory) { + @Qualifier("store-client") RestfulClientFactory clientFactory, + @Qualifier("base-client-trust") KeyStore trustStore) { logger.info("Setting up store client for direct access using {}.", EvaluationStrategy.CQL); @@ -122,7 +124,7 @@ IGenericClient client(@Qualifier("store-client") FhirContext fhirContext, Optional.ofNullable(oauthProxyPassword).map(p -> "'***'").orElse("none")); } client.registerInterceptor(new OAuthInterceptor(oauthClientId, oauthClientSecret, oauthIssuerUrl, - Optional.ofNullable(oauthProxyHost), Optional.ofNullable(oauthProxyPort), + trustStore, Optional.ofNullable(oauthProxyHost), Optional.ofNullable(oauthProxyPort), Optional.ofNullable(oauthProxyUsername), Optional.ofNullable(oauthProxyPassword))); } diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java index 844f164..418075c 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java @@ -9,15 +9,29 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.containers.BindMode.READ_ONLY; @Testcontainers public class OAuthInterceptorIT { protected static final Network DEFAULT_CONTAINER_NETWORK = Network.newNetwork(); + private static URL nginxConf = getResource("nginx.conf"); + private static URL nginxTestProxyConfTemplate = getResource("keycloak_reverse_proxy.conf.template"); + private static URL indexFile = getResource("index.html"); + private static URL serverCertChain = getResource("../certs/server_cert_chain.pem"); + private static URL serverCertKey = getResource("../certs/server_cert_key.pem"); + private static URL trustStoreFile = getResource("../certs/ca.p12"); @Container public static KeycloakContainer keycloak = new KeycloakContainer("quay.io/keycloak/keycloak:25.0") @@ -25,15 +39,30 @@ public class OAuthInterceptorIT { .withNetworkAliases("keycloak") .withAdminUsername("admin") .withAdminPassword("admin") + .withEnv("KC_PROXY_HEADERS", "xforwarded") .withRealmImportFile("de/medizininformatik_initiative/process/feasibility/client/store/realm-test.json") .withReuse(true); + @Container + public static GenericContainer proxy = new GenericContainer<>( + DockerImageName.parse("nginx:1.27.1")) + .withExposedPorts(8443) + .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) + .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) + .withFileSystemBind(nginxTestProxyConfTemplate.getPath(), + "/etc/nginx/templates/default.conf.template", READ_ONLY) + .withFileSystemBind(serverCertChain.getPath(), "/etc/nginx/certs/server_cert.pem", READ_ONLY) + .withFileSystemBind(serverCertKey.getPath(), "/etc/nginx/certs/server_cert_key.pem", READ_ONLY) + .withNetwork(DEFAULT_CONTAINER_NETWORK) + .withNetworkAliases("proxy") + .dependsOn(keycloak); + @Container public static GenericContainer forwardProxyNoAuth = new GenericContainer<>( DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withExposedPorts(8080) - .withFileSystemBind(getResource("forward_proxy.conf").getPath(), "/etc/squid/squid.conf", + .withFileSystemBind(getResource("keycloak_forward_proxy.conf").getPath(), "/etc/squid/squid.conf", BindMode.READ_ONLY); @Container @@ -41,16 +70,27 @@ public class OAuthInterceptorIT { DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withExposedPorts(8080) - .withFileSystemBind(getResource("forward_proxy_basic_auth.conf").getPath(), "/etc/squid/squid.conf", - BindMode.READ_ONLY) - .withFileSystemBind(getResource("forward_proxy.htpasswd").getPath(), "/etc/squid/passwd", + .withFileSystemBind(getResource("keycloak_forward_proxy_basic_auth.conf").getPath(), + "/etc/squid/squid.conf", BindMode.READ_ONLY) + .withFileSystemBind(getResource("keycloak_forward_proxy.htpasswd").getPath(), "/etc/squid/passwd", BindMode.READ_ONLY); @Test - public void getToken() { + public void getToken() throws Exception { String issuerUrl = "http://" + keycloak.getHost() + ":" + keycloak.getFirstMappedPort() + "/realms/test"; - OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, Optional.empty(), - Optional.empty(), Optional.empty(), Optional.empty()); + OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, getTrustStore(), + Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); + + String token = interceptor.getToken(); + + assertThat(token).isNotNull(); + } + + @Test + public void getTokenTls() throws Exception { + String issuerUrl = "https://" + proxy.getHost() + ":" + proxy.getFirstMappedPort() + "/realms/test"; + OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, getTrustStore(), + Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); String token = interceptor.getToken(); @@ -58,9 +98,22 @@ public void getToken() { } @Test - public void getTokenViaProxyNoAuth() { + public void getTokenViaForwardProxyNoAuth() throws Exception { String issuerUrl = "http://keycloak:8080/realms/test"; - OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, + OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, getTrustStore(), + Optional.of(forwardProxyNoAuth.getHost()), + Optional.of(forwardProxyNoAuth.getFirstMappedPort()), + Optional.empty(), Optional.empty()); + + String token = interceptor.getToken(); + + assertThat(token).isNotNull(); + } + + @Test + public void getTokenViaForwardProxyNoAuthTls() throws Exception { + String issuerUrl = "https://proxy:8443/realms/test"; + OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, getTrustStore(), Optional.of(forwardProxyNoAuth.getHost()), Optional.of(forwardProxyNoAuth.getFirstMappedPort()), Optional.empty(), Optional.empty()); @@ -70,10 +123,11 @@ public void getTokenViaProxyNoAuth() { assertThat(token).isNotNull(); } + /* Forward proxy with basic authentication only works for non-tls connections by default since Java 8u111. */ @Test - public void getTokenViaProxyBasicAuth() { + public void getTokenViaForwardProxyBasicAuth() throws Exception { String issuerUrl = "http://keycloak:8080/realms/test"; - OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, + OAuthInterceptor interceptor = new OAuthInterceptor("account", "test", issuerUrl, getTrustStore(), Optional.of(forwardProxyBasicAuth.getHost()), Optional.of(forwardProxyBasicAuth.getFirstMappedPort()), Optional.of("test"), @@ -84,6 +138,11 @@ public void getTokenViaProxyBasicAuth() { assertThat(token).isNotNull(); } + private static KeyStore getTrustStore() + throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, URISyntaxException { + return KeyStore.getInstance(new File(trustStoreFile.toURI()), "changeit".toCharArray()); + } + private static URL getResource(final String name) { return OAuthInterceptorIT.class.getResource(name); } diff --git a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy.conf b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy.conf similarity index 100% rename from mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy.conf rename to mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy.conf diff --git a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy.htpasswd b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy.htpasswd similarity index 100% rename from mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy.htpasswd rename to mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy.htpasswd diff --git a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy_basic_auth.conf b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy_basic_auth.conf similarity index 100% rename from mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/forward_proxy_basic_auth.conf rename to mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_forward_proxy_basic_auth.conf diff --git a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_reverse_proxy.conf.template b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_reverse_proxy.conf.template new file mode 100644 index 0000000..2b0aca2 --- /dev/null +++ b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/keycloak_reverse_proxy.conf.template @@ -0,0 +1,25 @@ +server { + listen 8443 ssl; + listen [::]:8443 ssl; + http2 on; + + ssl_certificate /etc/nginx/certs/server_cert.pem; + ssl_certificate_key /etc/nginx/certs/server_cert_key.pem; + ssl_protocols TLSv1.3; + ssl_prefer_server_ciphers off; + add_header Strict-Transport-Security "max-age=63072000" always; + + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + proxy_set_header X-Forwarded-Host $x_forwarded_host; + proxy_set_header X-Forwarded-Port $x_forwarded_port; + + location / { + set $upstream keycloak:8080; + proxy_pass http://$upstream; + proxy_read_timeout 43200s; + } +} diff --git a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/nginx.conf b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/nginx.conf index 516202d..fc03138 100644 --- a/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/nginx.conf +++ b/mii-process-feasibility/src/test/resources/de/medizininformatik_initiative/process/feasibility/client/store/nginx.conf @@ -21,5 +21,35 @@ http { sendfile on; keepalive_timeout 65; + # Check if a X-Forwarded-Proto header (set by reverse-proxy) is already present. If not take the scheme used to call our nginx server. + map $http_x_forwarded_proto $x_forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; # Note that if the reverse-proxy does not add a X-Forwarded-Proto header, it may be incorrect if the protocol used by the reverse proxy is not the same as the one on which your nginx server is listening. In this case you have no solution than harcode the correct value. + } + + # Check if a X-Forwarded-Host header (set by reverse-proxy) is already present. If not take the value of the 'Host' header. + map $http_x_forwarded_host $x_forwarded_host { + default $http_x_forwarded_host; + "" $http_host; + } + + # Set the default port of each scheme/protocol (80 for http, 443 for https) + map $x_forwarded_proto $default_http_port { + default 80; + "https" 443; + } + + # Extract the real port of the client request url (unfortunatly nginx has no variable to get this info) + map $http_host $request_port { + default $default_http_port; # If port not explicitely defined in url take the default one associated to the calling scheme/protocol (80 for http, 443 for https) + "~^[^\:]+:(?

\d+)$" $p; + } + + # Check if a X-Forwarded-Port header (set by reverse-proxy) is already present. If not take the port from the client request url + map $http_x_forwarded_port $x_forwarded_port { + default $http_x_forwarded_port; + "" $request_port; + } + include /etc/nginx/conf.d/*.conf; } From c5707bc662ad3edd0434b6820883bb8a864ff27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BChle?= Date: Wed, 11 Sep 2024 10:54:33 +0200 Subject: [PATCH 3/5] Remove Deprecated Plugin Folder for Java Libraries --- .../dic-1/bpe/plugin/README.md | 1 - .../dic-2/bpe/log/README.md | 1 - .../dic-2/bpe/plugin/README.md | 1 - .../dic-3/bpe/plugin/README.md | 1 - .../dic-4/bpe/plugin/README.md | 1 - .../docker-compose.yml | 16 ---------------- 6 files changed, 21 deletions(-) delete mode 100644 mii-process-feasibility-docker-test-setup/dic-1/bpe/plugin/README.md delete mode 100644 mii-process-feasibility-docker-test-setup/dic-2/bpe/log/README.md delete mode 100644 mii-process-feasibility-docker-test-setup/dic-2/bpe/plugin/README.md delete mode 100644 mii-process-feasibility-docker-test-setup/dic-3/bpe/plugin/README.md delete mode 100644 mii-process-feasibility-docker-test-setup/dic-4/bpe/plugin/README.md diff --git a/mii-process-feasibility-docker-test-setup/dic-1/bpe/plugin/README.md b/mii-process-feasibility-docker-test-setup/dic-1/bpe/plugin/README.md deleted file mode 100644 index 777e443..0000000 --- a/mii-process-feasibility-docker-test-setup/dic-1/bpe/plugin/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty folder for plugin jars \ No newline at end of file diff --git a/mii-process-feasibility-docker-test-setup/dic-2/bpe/log/README.md b/mii-process-feasibility-docker-test-setup/dic-2/bpe/log/README.md deleted file mode 100644 index 2fd366f..0000000 --- a/mii-process-feasibility-docker-test-setup/dic-2/bpe/log/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty folder for log files \ No newline at end of file diff --git a/mii-process-feasibility-docker-test-setup/dic-2/bpe/plugin/README.md b/mii-process-feasibility-docker-test-setup/dic-2/bpe/plugin/README.md deleted file mode 100644 index 777e443..0000000 --- a/mii-process-feasibility-docker-test-setup/dic-2/bpe/plugin/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty folder for plugin jars \ No newline at end of file diff --git a/mii-process-feasibility-docker-test-setup/dic-3/bpe/plugin/README.md b/mii-process-feasibility-docker-test-setup/dic-3/bpe/plugin/README.md deleted file mode 100644 index 777e443..0000000 --- a/mii-process-feasibility-docker-test-setup/dic-3/bpe/plugin/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty folder for plugin jars \ No newline at end of file diff --git a/mii-process-feasibility-docker-test-setup/dic-4/bpe/plugin/README.md b/mii-process-feasibility-docker-test-setup/dic-4/bpe/plugin/README.md deleted file mode 100644 index 777e443..0000000 --- a/mii-process-feasibility-docker-test-setup/dic-4/bpe/plugin/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty folder for plugin jars \ No newline at end of file diff --git a/mii-process-feasibility-docker-test-setup/docker-compose.yml b/mii-process-feasibility-docker-test-setup/docker-compose.yml index 88f35a7..cf459c0 100755 --- a/mii-process-feasibility-docker-test-setup/docker-compose.yml +++ b/mii-process-feasibility-docker-test-setup/docker-compose.yml @@ -305,10 +305,6 @@ services: - app_dic_1_client_certificate_private_key.pem - app_client_certificate_private_key.pem.password volumes: - - type: bind - source: ./dic-1/bpe/plugin - target: /opt/bpe/plugin - read_only: true - type: bind source: ./dic-1/bpe/process target: /opt/bpe/process @@ -501,10 +497,6 @@ services: - app_dic_2_client_certificate_private_key.pem - app_client_certificate_private_key.pem.password volumes: - - type: bind - source: ./dic-2/bpe/plugin - target: /opt/bpe/plugin - read_only: true - type: bind source: ./dic-2/bpe/process target: /opt/bpe/process @@ -654,10 +646,6 @@ services: - app_dic_3_client_certificate_private_key.pem - app_client_certificate_private_key.pem.password volumes: - - type: bind - source: ./dic-3/bpe/plugin - target: /opt/bpe/plugin - read_only: true - type: bind source: ./dic-3/bpe/process target: /opt/bpe/process @@ -841,10 +829,6 @@ services: - app_dic_4_client_certificate_private_key.pem - app_client_certificate_private_key.pem.password volumes: - - type: bind - source: ./dic-4/bpe/plugin - target: /opt/bpe/plugin - read_only: true - type: bind source: ./dic-4/bpe/process target: /opt/bpe/process From 8a1eae623ce4d4caaedd8a137cfe330f1f7e3279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BChle?= Date: Wed, 11 Sep 2024 11:00:12 +0200 Subject: [PATCH 4/5] Use DIC-3 Store with OAuth Authentication --- .../dic-3/keycloak/realm-test.json | 2056 +++++++++++++++++ .../dic-3/proxy/nginx.conf | 25 +- .../docker-compose.yml | 192 +- .../proxy/conf.d/dic-1.conf | 13 +- .../proxy/conf.d/dic-2.conf | 13 +- .../proxy/conf.d/dic-3.conf | 13 +- .../proxy/conf.d/dic-4.conf | 13 +- .../proxy/conf.d/zars.conf | 13 +- 8 files changed, 2272 insertions(+), 66 deletions(-) create mode 100644 mii-process-feasibility-docker-test-setup/dic-3/keycloak/realm-test.json diff --git a/mii-process-feasibility-docker-test-setup/dic-3/keycloak/realm-test.json b/mii-process-feasibility-docker-test-setup/dic-3/keycloak/realm-test.json new file mode 100644 index 0000000..7331910 --- /dev/null +++ b/mii-process-feasibility-docker-test-setup/dic-3/keycloak/realm-test.json @@ -0,0 +1,2056 @@ +{ + "id" : "test", + "realm" : "test", + "displayName" : "Keycloak", + "displayNameHtml" : "

Keycloak
", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 3600, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "clientSessionIdleTimeout" : 0, + "clientSessionMaxLifespan" : 0, + "clientOfflineSessionIdleTimeout" : 0, + "clientOfflineSessionMaxLifespan" : 0, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "oauth2DeviceCodeLifespan" : 600, + "oauth2DevicePollingInterval" : 5, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxTemporaryLockouts" : 0, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "cfab484f-be62-43ac-ac58-4a3ca0b76895", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "test", + "attributes" : { } + }, { + "id" : "a405bd09-e663-4e3c-9d77-a9d965d1250a", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "test", + "attributes" : { } + }, { + "id" : "76043e61-4a56-4b14-b70a-54f411d73f70", + "name" : "default-roles-test", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "test", + "attributes" : { } + }, { + "id" : "ddf3601e-7689-4e9a-8dce-69a964a14d8c", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "test-realm" : [ "view-users", "manage-events", "view-realm", "view-clients", "view-events", "query-realms", "query-users", "impersonation", "view-authorization", "manage-clients", "manage-identity-providers", "query-groups", "query-clients", "create-client", "manage-authorization", "view-identity-providers", "manage-users", "manage-realm" ] + } + }, + "clientRole" : false, + "containerId" : "test", + "attributes" : { } + }, { + "id" : "319558ae-0ae5-4110-b688-5f30f94f652e", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "test", + "attributes" : { } + } ], + "client" : { + "realm-management" : [ { + "id" : "62e4743e-a905-42a8-96d6-a8d5fdd844ea", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "6c73cf21-93e7-453d-8ba2-b3c7154c4367", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "d232c025-2d26-40ee-8196-cf52f171097b", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "6d7f5457-8f9a-4ffa-825a-fde1a755e09e", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "e6841db6-8b7e-4884-b2b4-65d950eaf8ac", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "manage-events", "view-identity-providers", "manage-identity-providers", "query-realms", "view-users", "manage-authorization", "view-clients", "view-realm", "create-client", "query-groups", "query-clients", "view-events", "manage-realm", "query-users", "view-authorization", "manage-clients", "manage-users", "impersonation" ] + } + }, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "b4a8f2f3-eed6-4957-b2c0-3f0eda65ccac", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "cf664a6f-60d6-4603-8242-f7c8aa7aabb4", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "4912268a-99a5-4d06-bac1-49153e9e6330", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "0660daed-6bb8-432c-8d65-4b7ccf3938e7", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "22510f81-7b5d-4ab4-b31f-a168a6d04f1d", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "9d4ba117-e4ac-4dda-80cd-5753f1443247", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "0ac7902c-0cfe-4ece-b694-a2e56b1a436a", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "2f91a5d6-4d8b-4e86-bc2b-98dafa5897a4", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "518da31b-1771-4fa0-ac0c-5bd9420776e9", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "bb608a9a-af7e-49d5-9306-c4925525129d", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "89e04b7d-dda2-47a5-8610-951601c52048", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "1e319aff-9893-482d-945d-d428ee73c014", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "9f68e090-fc30-43e9-8a6a-2e0f08c8b6a2", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + }, { + "id" : "6b633c77-15e4-4788-8920-9b3ea1f803a0", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "attributes" : { } + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "77f7ce3c-d305-45ff-810a-06fffe9285dd", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "738bfb28-835b-4707-b3fa-e8d620c4a2ad", + "attributes" : { } + } ], + "account" : [ { + "id" : "4cb842f2-27bd-4368-b99c-f505aa8b3247", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "6f3de551-2a00-4a4f-a304-0b8b5ddb7bcb", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "47a5291d-d89e-4c93-9a56-3b33b5944ace", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "92c23878-9e1d-4bd2-a73b-01d35c3a4a57", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "7ae6416a-3d1c-4fa5-8f6c-199672eb696b", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "4ac84e04-1a77-4121-bb6e-18ed6948ad93", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "54be8eec-70da-44f4-95a0-b4eb62800c8a", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + }, { + "id" : "8de14797-ac52-4001-8bad-ac66f326485e", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "attributes" : { } + } ], + "test-realm" : [ { + "id" : "154e52c7-8957-475e-9e32-193daf180c5a", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "test-realm" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "51de37c7-d9e9-44dc-8264-a5c34731101b", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "c6952b26-9c30-4ae4-96ad-bd8fc8803cde", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "test-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "11eef5a3-1b86-4f4b-81d2-73c21dee786a", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "c3a9ac36-2296-4c3c-9cad-4b2d3b2a8c92", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "e8d45b32-ee65-4d35-bb29-f49022dde86c", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "13a73a25-f362-4ff5-a8d2-97f1f451d8c7", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "25a98a91-87b0-42dc-9e25-18a0fb9a4f63", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "7c7d7e5b-a9a9-4b5e-a2b9-0efbfc205da0", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "d10d7200-2fa0-4ff9-81d2-0e6f1d1bcc19", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "ca756c34-6506-4461-a5ec-6ffabf008074", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "701964cd-ea25-4df7-87fe-090de21d2495", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "4526b5eb-206a-4843-a7c1-8cb59745c042", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "b70afed2-5c61-400e-867b-036bcdec58e3", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "06557d0f-4267-429d-96d8-92ccdaea9c22", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "3822acc8-a18d-41f7-ba08-f6fe287cd1d7", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "c6b461b5-a5c6-41f5-ab8f-742bfcf11cdd", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + }, { + "id" : "8b022167-a28f-4642-8e9b-b11fdf8e9b9c", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "76043e61-4a56-4b14-b70a-54f411d73f70", + "name" : "default-roles-test", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "test" + }, + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "localizationTexts" : { }, + "webAuthnPolicyRpEntityName" : "keycloak", + "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], + "users" : [ { + "id" : "b0ef6edd-d503-4c74-a5ac-587fc56ea8ec", + "username" : "admin", + "emailVerified" : false, + "createdTimestamp" : 1619179992044, + "enabled" : true, + "totp" : false, + "credentials" : [ { + "id" : "a364bc10-e50d-46e7-9a4b-a2e81cfb97ef", + "type" : "password", + "createdDate" : 1619179992264, + "secretData" : "{\"value\":\"HFaSOho+7v2/pNE05AzCJs+MGKga2UuZFpCJwrEwyRWXq8xhYI+QZlsrsvkXbg8yye0ajxvKMhoQ8StOIw92hQ==\",\"salt\":\"0FxKxt+bGWwoWSZptMOXlw==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "uma_authorization", "admin" ], + "clientRoles" : { + "account" : [ "view-profile", "manage-account" ] + }, + "notBefore" : 0, + "groups" : [ ] + }, { + "id" : "18fb5db1-ebae-4824-ba72-a412330fe026", + "username" : "john", + "firstName" : "John", + "lastName" : "Doe", + "emailVerified" : false, + "createdTimestamp" : 1710947689953, + "enabled" : true, + "totp" : false, + "credentials" : [ { + "id" : "beee2f20-4a46-41e3-ace8-c56dca1e351f", + "type" : "password", + "createdDate" : 1710947723777, + "secretData" : "{\"value\":\"XmSnkmkJIk2SiZmdURejFJeEV+Jrvwqfi4NIKBwvcHXpRKtyaUFRSZb+cLuy4YyhhGXK/jn7sIbY3lNg/OwJNA==\",\"salt\":\"Fe3FD77W0p8xSfIckS7BpQ==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":210000,\"algorithm\":\"pbkdf2-sha512\",\"additionalParameters\":{}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-test" ], + "notBefore" : 0, + "groups" : [ ] + }, { + "id" : "72a7f37e-b33f-4908-9ad9-33be0d4c1620", + "username" : "service-account-account", + "emailVerified" : false, + "createdTimestamp" : 1619180273352, + "enabled" : true, + "totp" : false, + "serviceAccountClientId" : "account", + "credentials" : [ ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "offline_access", "uma_authorization" ], + "clientRoles" : { + "account" : [ "view-profile", "manage-account" ] + }, + "notBefore" : 0, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "a0f23909-cbba-4950-95c5-1a166b4b3c54", + "clientId" : "account", + "name" : "${client_account}", + "description" : "", + "rootUrl" : "${authBaseUrl}", + "adminUrl" : "", + "baseUrl" : "/realms/test/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "test", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : true, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "saml.assertion.signature" : "false", + "saml.force.post.binding" : "false", + "saml.multivalued.roles" : "false", + "saml.encrypt" : "false", + "post.logout.redirect.uris" : "+", + "oauth2.device.authorization.grant.enabled" : "false", + "backchannel.logout.revoke.offline.tokens" : "false", + "saml.server.signature" : "false", + "saml.server.signature.keyinfo.ext" : "false", + "exclude.session.state.from.auth.response" : "false", + "oidc.ciba.grant.enabled" : "false", + "backchannel.logout.session.required" : "false", + "client_credentials.use_refresh_token" : "false", + "saml_force_name_id_format" : "false", + "saml.client.signature" : "false", + "tls.client.certificate.bound.access.tokens" : "false", + "saml.authnstatement" : "false", + "display.on.consent.screen" : "false", + "saml.onetimeuse.condition" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "df9007ce-cdcc-4cd3-be23-74cc3a81e518", + "name" : "Client IP Address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientAddress", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientAddress", + "jsonType.label" : "String" + } + }, { + "id" : "49dfb8da-2cf1-4348-a587-e11c8a2dd5e3", + "name" : "Client ID", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientId", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientId", + "jsonType.label" : "String" + } + }, { + "id" : "facf237e-6601-4712-a854-e52134dd5122", + "name" : "Client Host", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientHost", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientHost", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "a13c25c1-0378-466f-98eb-48006045968f", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/test/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "102c2a26-30b5-4dfe-a540-6bd925ceaa67", + "redirectUris" : [ "/realms/test/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "ccf3fe06-0eb7-4e2b-8323-7f53649d40d4", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "502c9394-9181-4ddc-b573-f0b545b2ca9c", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "2fe5724f-0328-4fe7-a4b7-37a0badf610f", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "ed0e9e16-d955-44d4-ab4c-0c6e8480bf12", + "clientId" : "test-realm", + "name" : "test Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "test", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "738bfb28-835b-4707-b3fa-e8d620c4a2ad", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "b2569a8e-0483-44aa-aa82-c2b3ee9462fc", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "b9e2f2c2-46ba-4d57-9f93-f336ad52a3bf", + "clientId" : "realm-management", + "name" : "${client_realm-management}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "9f6340e7-176f-44f0-ae0f-a04cc5c54921", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/test/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "50f03c48-3691-4c39-a3c3-3d02219525dc", + "redirectUris" : [ "/admin/test/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "69d66f56-d567-451f-b979-7be216edd68a", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "9809d86e-9b9d-4c77-96d9-483f79bbadf7", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${emailScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "5cb5d135-4ec0-48ee-b8f3-1d2eea8972a5", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "cd8a5107-e52c-4642-942e-d05bff239e3c", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "f3bb04c6-97c8-47e0-b383-8e7e586d2ab8", + "name" : "offline_access", + "description" : "OpenID Connect built-in scope: offline_access", + "protocol" : "openid-connect", + "attributes" : { + "consent.screen.text" : "${offlineAccessScopeConsentText}", + "display.on.consent.screen" : "true" + } + }, { + "id" : "f3f3fa4a-0e7e-4ffa-a994-6297c23f908d", + "name" : "web-origins", + "description" : "OpenID Connect scope for add allowed web origins to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false", + "consent.screen.text" : "" + }, + "protocolMappers" : [ { + "id" : "91fa2894-4e7e-404b-864e-c917f90ac77b", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "3b1fce21-ed51-4f05-942c-93cecb81025c", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${profileScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "351876fb-061f-4c8d-838c-082928bd80f7", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "a4d2a8c3-36d2-4f5a-91eb-a570e7cc0d3c", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "String" + } + }, { + "id" : "7492477a-d4c6-4a9e-89b2-6335a5f89ada", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "fe14acb2-1948-49d6-9b2c-ba20b64cf017", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "28db7700-4226-4307-a22a-0deb6f857513", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "ec4bdc29-7979-45f0-9071-4b680fda049a", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "84d327bb-bd09-4428-b6e3-e5ba4d896074", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "6258fd50-c687-4a42-8b7c-964b75581042", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "9db28236-3a1a-4e8d-b5cd-13f689f180a0", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "ae46ed2c-2154-45ef-90a7-fa50e80dc935", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "9a4a3bd9-b8ee-4ebc-94b4-b4da3881ae18", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "ebc6c1fe-d2cb-441f-8803-c4ec8506168c", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "cb2a2a4d-a3d2-4660-9438-714f64c4f831", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "7e28b8ae-83b8-4f06-9184-932a06b5e619", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "8dc47e1e-202a-4aa4-945d-1e4a80763482", + "name" : "acr", + "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "7ac4dd59-25b7-42cc-a8c9-68301983dce9", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "bd5a5fc6-85c8-4e4b-b147-0dbbfd5add27", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${phoneScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "94fa890b-976e-48ce-8640-6b6781e7bf6c", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + }, { + "id" : "deb58ea8-1660-43ac-9097-34d38b3c9126", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + } ] + }, { + "id" : "06ee6c91-072f-461f-be27-791a6556324f", + "name" : "microprofile-jwt", + "description" : "Microprofile - JWT built-in scope", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "efccbda2-dd10-426b-809a-f46cb921c7a9", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "73bccc6d-2d3f-4c85-8d25-c6868f2b70b8", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "f4cb8558-578a-41bb-815a-91f2514b71cb", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${rolesScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "63a2ee31-2194-49cc-9724-ccb9c57d8fa2", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "da083c4e-081c-4f8f-8526-5fa49d71a111", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + }, { + "id" : "8d7c0a1a-42cc-4efe-a322-3c56ded3424e", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + } ] + }, { + "id" : "992bf614-54e3-414a-8d56-e47d7e37fc11", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${addressScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "a1999995-852d-4c55-b2bc-e096aba293f2", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + }, { + "id" : "f0cb84ff-70eb-42ee-8439-da9cfd3c62ca", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "dba527ed-7819-4a95-8102-0c9032f25067", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "profile", "email", "role_list", "web-origins", "roles", "acr" ], + "defaultOptionalClientScopes" : [ "microprofile-jwt", "address", "phone", "offline_access" ], + "browserSecurityHeaders" : { + "contentSecurityPolicyReportOnly" : "", + "xContentTypeOptions" : "nosniff", + "referrerPolicy" : "no-referrer", + "xRobotsTag" : "none", + "xFrameOptions" : "SAMEORIGIN", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection" : "1; mode=block", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "identityProviders" : [ ], + "identityProviderMappers" : [ ], + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "da2969b9-5e9b-448c-86ea-36cc860a3927", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "c2436a16-6e52-4161-949c-5747d4819497", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "3a935ca4-e98e-4ec1-ad6e-91023fc1eb4e", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "86ea8008-be05-4317-9ca9-b711ea4a8c13", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "8b7ad61a-9124-4a0d-aa25-57d99eaaba1b", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "4c31d0d7-6787-4c0f-8b41-799ff1e4b1e3", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper" ] + } + }, { + "id" : "fe477953-0991-4166-9239-8d020e9bb8f6", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "c3d4ebb9-7e9d-4cc8-97e2-3c3ce73da642", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper" ] + } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "27ee9f9c-a76b-4ed5-9dea-52a5108b85d8", + "providerId" : "declarative-user-profile", + "subComponents" : { }, + "config" : { + "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" ] + } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "16e1431e-e111-4466-a89e-3eaba25f9419", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "d352b3e0-4ad7-4698-8831-63fa4cc5e6b7" ], + "secret" : [ "njkg8Vd2htEmKQdm9nntcgvQEuY8Tegl0d0LaB7hSpkQz0tpfbkAip1Myzs8ULQ8Y4ZMb7ddb5dgLQXJFFILh9ji1RbM3W3ZkD4m9CU14-O7tjwL0mNk_ER99393X9f6jUDMmll2lqEmFkxBUJr5G0Sqi1MyhSaXjaQfFlWpfrY" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } + }, { + "id" : "185b5cbc-c208-4b30-8ea4-e26d46827d8a", + "name" : "fallback-RS256", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAsRMbt+R+Fkym/pDoprcMQG+QuaHI0IheBXUoSl160A2TIeF6vJzbpRex1sNbTBUcfpeYesrWoevpzmk43uDWcMtLSo2cDr6pt8Gfa97V5LH1tVF+RcdwebirKdzH0kh6t8RTxN81cnl564LWz5VJvHCCPJcSvegUM6gprHVIwtlpEMzsoC2lFQNjCjfEl2aY5LPuvD9bWjeeDK/J4s5wKgr2Y9A12zjTvGKJkKDEam/4cKVapi+sGNNafrAX0DcrEM0G2S1S+FefjIOqF50mOKhRJbNkUcbK/g/VKDBCdowzmvvR6MZx0rBi7RrHhaq8KToXoYcOIvMOKAvpDc1gjwIDAQABAoIBAB9AvyCqzHJFHyhJDTb3kcsBpeqNmnLrzqRp9C2D6Dw2WSSetln52W5/Cx1bp457H2dcfEYX7N/xUnfi7G2yA0cvKl/DNKsJjczn+KpCT0ApBLP26TGJrNle9Z7S39XGgxpSJXLW7okA1brygdVrhPMkbGgjReSMxJwFby2IGcqB53oAeCgZEKkW4ZqOh/cwKjJkLCgLRT9pgh875wniKDFeKnEx5sbNZ9dWPoqmy55TfjqjTGA3cdnWThnGNgGxiN3fG2ZAPFxNAUpaBnlHPiaPGZJwv2lDisAKzP+MnA5+wz1Wx0ncEs08Aw5ngtFpljC5zktNhkmCRGlJOFLGmQkCgYEA5rpd4rg5uwtN7OKCksATRRjkLWEVgqoggW4ejnJ6LSQ+VY6OdV77nC1ftOEeddYouYtfcRAfhxhKtHPJI14IRzhGevvQcN65jnUhaoYk5N6bKHK349l0jhK5UmZAyCdQpY7N+iNAQLOrIqSL87I0B+jd8QGFu8IssR+gnEw0f40CgYEAxHhL+mxc+tUn2JxAZJiIyh+M8vLvTRCGRMW9gxtQ6w8K47rYiY93veIMU/2gk9PLYhUcU4Uz14MQfuldiuamydTw1wn3e7pgLD1EQ29Ck2vcr+nLz5G6z55wfiV4rqvb1xSnu0u5Y/k5Kopo9G2U20kDfWyNbQvXpnRSCKgJW4sCgYEAt0ji3gCUs7Y2L/B741G7vQ8Z68aMjODSs56jnWrpDUUWU2bMWgaa/6S3u3t9dAQtE7/YkHtLYEj2x0SXSoYfM1xL+NRi79auNrFrWzC2zCzdupLu64xJ37aWCxP5cEZy9SFtFMC+AOf5Ear/FhbA6GufKx2Xe+CzGf1S2/ZZWd0CgYEAlaiVJ8NX6HJqkeQkYPyYZm82LPLFOsz1mnmObMpoD0Y8I1D3FYJF0kzY2zn+Ed1pteMi2rRC002xSRt2+BHOxzv/4a5j6MoF7G0XDM85xZaKWy4a5Ji71t94DX95uISNR/8h7dg29mKoGzGn1VmL5KZvlCEWchRtRwygWJu31RUCgYBbKIVikkdS1ZxexPmXAISKZ+cO+RUffLjs6RLgE/Bt1LZLCK4gA3y3HaBfkcF4LSoXjwF35mDAQ32ZP24afasHjTwcREv1vBzhvKEppWpsaZC7pr9IJfYHhPxhHbkHD2BdxKRMg/jQ5N7cLjuqenR0DY1C4mTcYSA1W1DqezrmrQ==" ], + "certificate" : [ "MIICmzCCAYMCBgF4/qYe7zANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjEwNDIzMTIxMTQzWhcNMzEwNDIzMTIxMzIzWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxExu35H4WTKb+kOimtwxAb5C5ocjQiF4FdShKXXrQDZMh4Xq8nNulF7HWw1tMFRx+l5h6ytah6+nOaTje4NZwy0tKjZwOvqm3wZ9r3tXksfW1UX5Fx3B5uKsp3MfSSHq3xFPE3zVyeXnrgtbPlUm8cII8lxK96BQzqCmsdUjC2WkQzOygLaUVA2MKN8SXZpjks+68P1taN54Mr8niznAqCvZj0DXbONO8YomQoMRqb/hwpVqmL6wY01p+sBfQNysQzQbZLVL4V5+Mg6oXnSY4qFEls2RRxsr+D9UoMEJ2jDOa+9HoxnHSsGLtGseFqrwpOhehhw4i8w4oC+kNzWCPAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACl0r90/fEbh6Ka8wKlV/8vtqv2TScgC+u1YSdXbA6AgoNhCOLo6+8IA6thV6pV918lzylIB1BpB4eaxN9R0EawErAYOJflw3zeUM2lbu5CIv6xe5MOcRGTqvQGFlPfiY07ug3aS15M0V6oNNdPYHgM6712Wyslsl1Bx/Weim/KeRqrjU1aedeC5GTi1znQqF+w9cc9WNEH4QVvDmzM6rmSrSTE4NkCxl3qNhKbISsZrb3mWQq9Xlli7RWSWLYnaN7/6X+PViWgMI1zugjqt4tOKKoRM7yeqHFqk98TpcG8DfAxFlnUBuQCDnKE5ntH6draRVft4K+N+fhL3B2PyG0M=" ], + "priority" : [ "-100" ], + "algorithm" : [ "RS256" ] + } + }, { + "id" : "5769f531-07cd-4e4e-a565-3d8731daafdd", + "name" : "fallback-HS256", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "73170ee0-e952-4573-8d9c-d6a9fb2c193e" ], + "secret" : [ "jlNrWr4_mB4AOXdLF7izVHaOT7rmfssy0_5hXWWVBN1G3vosStn_mO27HwdRBiALb-Ri24X83sBj_JjwJ_s3QpyJQqejTDm61_H6zCFcmD1c89-iNZc_45hSbDj38wX4rfmB7F67r254cHh5q2TcdJvqDJfuViGPS1TiRGoxWb4" ], + "priority" : [ "-100" ], + "algorithm" : [ "HS256" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "f9e9054d-fedc-43b1-b0ff-8fbf84d665f9", + "alias" : "Account verification options", + "description" : "Method with which to verity the existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-email-verification", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false + } ] + }, { + "id" : "67760bda-4d3f-462d-a81d-5b99fdbd9057", + "alias" : "Browser - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "ad30bc5a-daeb-4e39-b11c-4d209227378e", + "alias" : "Direct Grant - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "d66d7cc2-f395-4e6f-b1f2-f3c650cc1223", + "alias" : "First broker login - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "985ffbbb-267f-4cb6-a09b-454ebb9e5b60", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Account verification options", + "userSetupAllowed" : false + } ] + }, { + "id" : "5bdd0a60-8aeb-4e11-9455-ae01eed15bda", + "alias" : "Reset - Conditional OTP", + "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "7793fa6d-5be1-498b-9337-170426960cb6", + "alias" : "User creation or linking", + "description" : "Flow for the existing/non-existing user alternatives", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false + } ] + }, { + "id" : "38468f69-d630-4b00-ab5b-169e7a413b44", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "First broker login - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "c7324105-a924-4689-8f04-c7ea0f8effd2", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-spnego", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "identity-provider-redirector", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 25, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "forms", + "userSetupAllowed" : false + } ] + }, { + "id" : "88e04d13-4d71-4ff6-b521-7bbebb3329f5", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-secret-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-x509", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 40, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "c5c23ac7-c748-48d2-8090-7c21197238af", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "Direct Grant - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "a3201f31-10e7-4b6c-85a7-169851b5e3b4", + "alias" : "docker auth", + "description" : "Used by Docker clients to authenticate against the IDP", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "docker-http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "fa162a5a-0fb5-404f-8aa3-893fec90e1c9", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "User creation or linking", + "userSetupAllowed" : false + } ] + }, { + "id" : "784b94b0-b050-406a-83fb-e83eea2e282b", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Browser - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "9b62475b-9803-48ef-8c37-4786889773a4", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : true, + "flowAlias" : "registration form", + "userSetupAllowed" : false + } ] + }, { + "id" : "8c4579e2-0870-48c3-9b7b-faf6e1e7cb58", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-password-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 50, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-recaptcha-action", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 60, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "d8526a3d-2a46-429d-95b1-e0eec86a0130", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-credential-email", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 40, + "autheticatorFlow" : true, + "flowAlias" : "Reset - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "1cd0d9f7-bef8-4cfc-b1fe-bedb4aad0a7a", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "fdc6ae68-fe17-43fe-b7b8-0fcc04d822ce", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "c84572ec-5ca1-4730-817a-b7a4ca89bf79", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "priority" : 10, + "config" : { } + }, { + "alias" : "TERMS_AND_CONDITIONS", + "name" : "Terms and Conditions", + "providerId" : "TERMS_AND_CONDITIONS", + "enabled" : false, + "defaultAction" : false, + "priority" : 20, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "priority" : 30, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 40, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "priority" : 50, + "config" : { } + }, { + "alias" : "delete_account", + "name" : "Delete Account", + "providerId" : "delete_account", + "enabled" : false, + "defaultAction" : false, + "priority" : 60, + "config" : { } + }, { + "alias" : "update_user_locale", + "name" : "Update User Locale", + "providerId" : "update_user_locale", + "enabled" : true, + "defaultAction" : false, + "priority" : 1000, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "firstBrokerLoginFlow" : "first broker login", + "attributes" : { + "cibaBackchannelTokenDeliveryMode" : "poll", + "cibaExpiresIn" : "120", + "cibaAuthRequestedUserHint" : "login_hint", + "oauth2DeviceCodeLifespan" : "600", + "clientOfflineSessionMaxLifespan" : "0", + "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", + "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "clientOfflineSessionIdleTimeout" : "0", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "24.0.1", + "userManagedAccessAllowed" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +} diff --git a/mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf b/mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf index 504f9ca..dbf6bff 100644 --- a/mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf +++ b/mii-process-feasibility-docker-test-setup/dic-3/proxy/nginx.conf @@ -27,18 +27,35 @@ http { ssl_prefer_server_ciphers off; add_header Strict-Transport-Security "max-age=63072000" always; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + server { listen 443 ssl; listen [::]:443 ssl; http2 on; + server_name dic-3-store-proxy; location / { - auth_basic "dic_3_store_auth"; - auth_basic_user_file /run/secrets/dic_3_store_proxy.htpasswd; + set $store_upstream dic-3-store:8080; + proxy_pass http://$store_upstream; - proxy_set_header X-ClientCert $ssl_client_escaped_cert; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 43200s; + } + } - proxy_pass http://172.10.0.117:8080; + server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name dic-3-keycloak-proxy; + + location / { + set $keycloak_upstream dic-3-keycloak:8080; + proxy_pass http://$keycloak_upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; diff --git a/mii-process-feasibility-docker-test-setup/docker-compose.yml b/mii-process-feasibility-docker-test-setup/docker-compose.yml index cf459c0..297f11e 100755 --- a/mii-process-feasibility-docker-test-setup/docker-compose.yml +++ b/mii-process-feasibility-docker-test-setup/docker-compose.yml @@ -1,9 +1,8 @@ -version: '3.8' services: # ---- Static cURL binary for health check in HAPI container hapi-curl-download: - image: alpine:3.18 + image: alpine:3.20 command: > sh -c "wget https://github.com/moparisthebest/static-curl/releases/download/v8.1.2/curl-amd64 -O /opt/bin/curl && chmod +x /opt/bin/curl" @@ -38,15 +37,10 @@ services: read_only: true networks: zars-fhir-frontend: - ipv4_address: 172.10.0.66 dic-1-fhir-frontend: - ipv4_address: 172.10.0.82 dic-2-fhir-frontend: - ipv4_address: 172.10.0.98 dic-3-fhir-frontend: - ipv4_address: 172.10.0.114 dic-4-fhir-frontend: - ipv4_address: 172.10.0.130 internet: aliases: - zars @@ -94,7 +88,7 @@ services: # ---- ZARS - FHIR Inbox ---------------------------------------------------- zars-fhir-app: - image: ghcr.io/datasharingframework/fhir:1.3.1 + image: ghcr.io/datasharingframework/fhir:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -151,7 +145,6 @@ services: - http://dsf.dev/fhir/CodeSystem/practitioner-role|DSF_ADMIN networks: zars-fhir-frontend: - ipv4_address: 172.10.0.69 zars-fhir-backend: internet: depends_on: @@ -163,7 +156,7 @@ services: # ---- ZARS - BPE ----------------------------------------------------------- zars-bpe-app: - image: ghcr.io/datasharingframework/bpe:1.3.1 + image: ghcr.io/datasharingframework/bpe:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -209,6 +202,7 @@ services: DEV_DSF_BPE_DB_USER_CAMUNDA_GROUP: zars_camunda_users DEV_DSF_BPE_DB_USER_CAMUNDA_USERNAME: zars_camunda_server_user DEV_DSF_BPE_FHIR_SERVER_BASE_URL: https://zars/fhir + DEV_DSF_BPE_PROCESS_EXCLUDED: medizininformatik-initiativede_feasibilityExecute|0.0 networks: zars-bpe-frontend: zars-bpe-backend: @@ -223,7 +217,7 @@ services: # ---- DIC-1 - FHIR --------------------------------------------------------- dic-1-fhir-app: - image: ghcr.io/datasharingframework/fhir:1.3.1 + image: ghcr.io/datasharingframework/fhir:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -277,7 +271,6 @@ services: - PERMANENT_DELETE networks: dic-1-fhir-frontend: - ipv4_address: 172.10.0.83 dic-1-fhir-backend: internet: depends_on: @@ -289,7 +282,7 @@ services: # ---- DIC-1 - BPE ---------------------------------------------------------- dic-1-bpe-app: - image: ghcr.io/datasharingframework/bpe:1.3.1 + image: ghcr.io/datasharingframework/bpe:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -331,6 +324,7 @@ services: DEV_DSF_BPE_DB_USER_CAMUNDA_GROUP: dic_1_camunda_users DEV_DSF_BPE_DB_USER_CAMUNDA_USERNAME: dic_1_camunda_server_user DEV_DSF_BPE_FHIR_SERVER_BASE_URL: https://dic-1/fhir + DEV_DSF_BPE_PROCESS_EXCLUDED: medizininformatik-initiativede_feasibilityRequest|0.0 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_FLARE_BASE_URL: http://dic-1-store:8080/ DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_FLARE_TIMEOUT_CONNECT: 2000 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_STRATEGY: structured-query @@ -415,7 +409,7 @@ services: # ---- DIC-2 - FHIR --------------------------------------------------------- dic-2-fhir-app: - image: ghcr.io/datasharingframework/fhir:1.3.1 + image: ghcr.io/datasharingframework/fhir:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -469,7 +463,6 @@ services: - PERMANENT_DELETE networks: dic-2-fhir-frontend: - ipv4_address: 172.10.0.99 dic-2-fhir-backend: internet: depends_on: @@ -481,7 +474,7 @@ services: # ---- DIC-2 - BPE ---------------------------------------------------------- dic-2-bpe-app: - image: ghcr.io/datasharingframework/bpe:1.3.1 + image: ghcr.io/datasharingframework/bpe:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -523,6 +516,7 @@ services: DEV_DSF_BPE_DB_USER_CAMUNDA_GROUP: dic_2_camunda_users DEV_DSF_BPE_DB_USER_CAMUNDA_USERNAME: dic_2_camunda_server_user DEV_DSF_BPE_FHIR_SERVER_BASE_URL: https://dic-2/fhir + DEV_DSF_BPE_PROCESS_EXCLUDED: medizininformatik-initiativede_feasibilityRequest|0.0 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_BASE_URL: http://dic-2-store:8080/fhir DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_STRATEGY: cql DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_OBFUSCATE: "true" @@ -566,7 +560,7 @@ services: # ---- DIC-3 - FHIR --------------------------------------------------------- dic-3-fhir-app: - image: ghcr.io/datasharingframework/fhir:1.3.1 + image: ghcr.io/datasharingframework/fhir:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -620,7 +614,6 @@ services: - PERMANENT_DELETE networks: dic-3-fhir-frontend: - ipv4_address: 172.10.0.115 dic-3-fhir-backend: internet: depends_on: @@ -629,7 +622,7 @@ services: # ---- DIC-3 - BPE ---------------------------------------------------------- dic-3-bpe-app: - image: ghcr.io/datasharingframework/bpe:1.3.1 + image: ghcr.io/datasharingframework/bpe:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -656,7 +649,10 @@ services: - type: bind source: ./dic-3/bpe/cache target: /opt/bpe/cache + ports: + - 5005:5005 environment: + EXTRA_JVM_ARGS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 TZ: Europe/Berlin DEV_DSF_SERVER_AUTH_TRUST_CLIENT_CERTIFICATE_CAS: /run/secrets/app_client_trust_certificates.pem DEV_DSF_BPE_DB_LIQUIBASE_PASSWORD_FILE: /run/secrets/db_liquibase.password @@ -672,10 +668,12 @@ services: DEV_DSF_BPE_DB_USER_CAMUNDA_GROUP: dic_3_camunda_users DEV_DSF_BPE_DB_USER_CAMUNDA_USERNAME: dic_3_camunda_server_user DEV_DSF_BPE_FHIR_SERVER_BASE_URL: https://dic-3/fhir + DEV_DSF_BPE_PROCESS_EXCLUDED: medizininformatik-initiativede_feasibilityRequest|0.0 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_TRUST_STORE_PATH: /run/secrets/dic_3_store_proxy_self_signed_ca.p12 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_TRUST_STORE_PASSWORD: "testpw" - DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_AUTH_BASIC_USERNAME: test - DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_AUTH_BASIC_PASSWORD: PF4Q4pEpXFkYToPSDre5tFr9P9MkqeDc + DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_AUTH_OAUTH_ISSUER_URL: "https://dic-3-keycloak-proxy/realms/test" + DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_AUTH_OAUTH_CLIENT_ID: "account" + DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_AUTH_OAUTH_CLIENT_PASSWORD: "test" DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_BASE_URL: https://dic-3-store-proxy/fhir DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_STRATEGY: cql DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_OBFUSCATE: "false" @@ -690,12 +688,35 @@ services: dic-3-fhir-app: condition: service_healthy restart: true - dedicated-dic-3-store-proxy: + dic-3-store-proxy: + condition: service_healthy + dic-3-keycloak: condition: service_healthy # ---- DIC-3 - DEDICATED PROXY WITH SELF SIGNED CERT ------------------------ - dedicated-dic-3-store-proxy: - image: nginx:1.25.1 + dic-3-keycloak: + image: "keycloak/keycloak:25.0.1" + command: ["start", "--import-realm"] + healthcheck: + test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000;echo -e \"GET /health/ready HTTP/1.1\r\nhost: localhost\r\nConnection: close\r\n\r\n\" >&3;grep \"HTTP/1.1 200 OK\" <&3"] + interval: "5s" + timeout: "5s" + retries: 3 + start_period: "30s" + networks: + dic-3-keycloak: + environment: + KC_HOSTNAME: "https://dic-3-keycloak-proxy" + KC_HOSTNAME_ADMIN: "https://dic-3-keycloak-proxy" + KC_HTTP_RELATIVE_PATH: "/" + KC_PROXY_HEADERS: "xforwarded" + KC_HTTP_ENABLED: "true" + KC_HEALTH_ENABLED: "true" + KC_LOG_LEVEL: "info" + volumes: + - "./dic-3/keycloak/realm-test.json:/opt/keycloak/data/import/realm-test.json" + dic-3-store-proxy: + image: nginx:1.27.1 restart: on-failure healthcheck: test: ["CMD-SHELL", "curl -ks https://localhost || exit 1"] @@ -710,16 +731,17 @@ services: - dic_3_store_proxy.htpasswd volumes: - type: bind - source: ./dic-3-store-proxy/nginx.conf + source: ./dic-3/proxy/nginx.conf target: /etc/nginx/nginx.conf read_only: true networks: dic-3-fhir-frontend: - ipv4_address: 172.10.0.116 dic-3-bpe-backend: + dic-3-keycloak: internet: aliases: - dic-3-store-proxy + - dic-3-keycloak-proxy environment: TZ: Europe/Berlin depends_on: @@ -727,22 +749,27 @@ services: # ---- DIC-3 - FHIR Data Store ---------------------------------------------- dic-3-store: - image: samply/blaze:0.24 + image: samply/blaze:0.30.0 restart: on-failure healthcheck: test: [ "CMD", "curl", "http://localhost:8080/health" ] interval: 10s timeout: 15s retries: 5 + secrets: + - dic_3_store_proxy_self_signed_ca.p12 ports: - "8072:8080" environment: - BASE_URL: http://localhost:8072 + BASE_URL: https://dic-3-store-proxy LOG_LEVEL: debug + OPENID_PROVIDER_URL: "https://dic-3-keycloak-proxy/realms/test" + OPENID_CLIENT_TRUST_STORE: "/run/secrets/dic_3_store_proxy_self_signed_ca.p12" + OPENID_CLIENT_TRUST_STORE_PASS: "testpw" networks: dic-3-fhir-frontend: - ipv4_address: 172.10.0.117 dic-3-bpe-backend: + internet: volumes: - type: volume source: dic-3-store-data @@ -750,7 +777,7 @@ services: # ---- DIC-4 - FHIR --------------------------------------------------------- dic-4-fhir-app: - image: ghcr.io/datasharingframework/fhir:1.3.1 + image: ghcr.io/datasharingframework/fhir:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -804,7 +831,6 @@ services: - PERMANENT_DELETE networks: dic-4-fhir-frontend: - ipv4_address: 172.10.0.131 dic-4-fhir-backend: internet: depends_on: @@ -813,7 +839,7 @@ services: # ---- DIC-4 - BPE ---------------------------------------------------------- dic-4-bpe-app: - image: ghcr.io/datasharingframework/bpe:1.3.1 + image: ghcr.io/datasharingframework/bpe:1.5.2 restart: on-failure healthcheck: test: [ "CMD-SHELL", "./healthcheck.sh" ] @@ -855,6 +881,7 @@ services: DEV_DSF_BPE_DB_USER_CAMUNDA_GROUP: dic_4_camunda_users DEV_DSF_BPE_DB_USER_CAMUNDA_USERNAME: dic_4_camunda_server_user DEV_DSF_BPE_FHIR_SERVER_BASE_URL: https://dic-4/fhir + DEV_DSF_BPE_PROCESS_EXCLUDED: medizininformatik-initiativede_feasibilityRequest|0.0 DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_CLIENT_STORE_BASE_URL: http://dic-4-store:8080/fhir DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_STRATEGY: cql DE_MEDIZININFORMATIK_INITIATIVE_FEASIBILITY_DSF_PROCESS_EVALUATION_OBFUSCATE: "false" @@ -1029,67 +1056,148 @@ secrets: networks: internet: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.0/26 zars-fhir-frontend: driver: bridge ipam: driver: default config: - - subnet: 172.10.0.64/28 + - subnet: 172.10.0.64/29 zars-fhir-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.72/29 zars-bpe-frontend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.80/29 zars-bpe-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.88/29 dic-1-fhir-frontend: driver: bridge ipam: driver: default config: - - subnet: 172.10.0.80/28 + - subnet: 172.10.0.96/29 dic-1-fhir-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.104/29 dic-1-bpe-frontend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.112/29 dic-1-bpe-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.120/29 dic-2-fhir-frontend: driver: bridge ipam: driver: default config: - - subnet: 172.10.0.96/28 + - subnet: 172.10.0.128/29 dic-2-fhir-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.136/29 dic-2-bpe-frontend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.144/29 dic-2-bpe-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.152/29 dic-3-fhir-frontend: driver: bridge ipam: driver: default config: - - subnet: 172.10.0.112/28 + - subnet: 172.10.0.160/29 dic-3-fhir-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.168/29 dic-3-bpe-frontend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.176/29 dic-3-bpe-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.184/29 + dic-3-keycloak: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.192/29 dic-4-fhir-frontend: driver: bridge ipam: driver: default config: - - subnet: 172.10.0.128/28 + - subnet: 172.10.0.200/29 dic-4-fhir-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.208/29 dic-4-bpe-frontend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.216/29 dic-4-bpe-backend: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.10.0.224/29 volumes: hapi-curl-binary: - name: "hapi-curl-binary" dic-1-store-data: - name: "dic-1-store-data" dic-2-store-data: - name: "dic-2-store-data" dic-3-store-data: - name: "dic-3-store-data" dic-4-store-data: - name: "dic-4-store-data" db-data: name: "db-data-mii-dsf-process-feasibility" diff --git a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-1.conf b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-1.conf index 73455b9..95e8c59 100644 --- a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-1.conf +++ b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-1.conf @@ -1,16 +1,21 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; server_name dic-1; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + location / { proxy_set_header X-ClientCert $ssl_client_escaped_cert; - proxy_pass http://172.10.0.83:8080; + set $upstream dic-1-fhir-app:8080; + proxy_pass http://$upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_read_timeout 43200s; + proxy_read_timeout 43200s; } } diff --git a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-2.conf b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-2.conf index 8ed5082..7cd91c6 100644 --- a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-2.conf +++ b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-2.conf @@ -1,16 +1,21 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; server_name dic-2; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + location / { proxy_set_header X-ClientCert $ssl_client_escaped_cert; - proxy_pass http://172.10.0.99:8080; + set $upstream dic-2-fhir-app:8080; + proxy_pass http://$upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_read_timeout 43200s; + proxy_read_timeout 43200s; } } diff --git a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-3.conf b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-3.conf index 1e14375..fa50353 100644 --- a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-3.conf +++ b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-3.conf @@ -1,16 +1,21 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; server_name dic-3; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + location / { proxy_set_header X-ClientCert $ssl_client_escaped_cert; - proxy_pass http://172.10.0.115:8080; + set $upstream dic-3-fhir-app:8080; + proxy_pass http://$upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_read_timeout 43200s; + proxy_read_timeout 43200s; } } diff --git a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-4.conf b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-4.conf index 5656ded..5a9b3ff 100644 --- a/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-4.conf +++ b/mii-process-feasibility-docker-test-setup/proxy/conf.d/dic-4.conf @@ -1,16 +1,21 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; server_name dic-4; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + location / { proxy_set_header X-ClientCert $ssl_client_escaped_cert; - proxy_pass http://172.10.0.131:8080; + set $upstream dic-4-fhir-app:8080; + proxy_pass http://$upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_read_timeout 43200s; + proxy_read_timeout 43200s; } } diff --git a/mii-process-feasibility-docker-test-setup/proxy/conf.d/zars.conf b/mii-process-feasibility-docker-test-setup/proxy/conf.d/zars.conf index 48db0b6..2de7f61 100644 --- a/mii-process-feasibility-docker-test-setup/proxy/conf.d/zars.conf +++ b/mii-process-feasibility-docker-test-setup/proxy/conf.d/zars.conf @@ -1,16 +1,21 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; server_name zars; + # DNS resolver needed for Docker + resolver 127.0.0.11 valid=10s; + location / { proxy_set_header X-ClientCert $ssl_client_escaped_cert; - proxy_pass http://172.10.0.69:8080; + set $upstream zars-fhir-app:8080; + proxy_pass http://$upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_read_timeout 43200s; + proxy_read_timeout 43200s; } } From 9d632f2da604dbe413e1d0655db3543ae90939c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20R=C3=BChle?= Date: Wed, 11 Sep 2024 16:54:16 +0200 Subject: [PATCH 5/5] Update Test Container Docker Images --- .../client/flare/FlareWebserviceClientImplBaseIT.java | 4 ++-- .../FlareWebserviceClientImplFwdProxyBasicAuthIT.java | 2 +- ...entImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT.java | 4 ++-- ...ebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT.java | 4 ++-- .../client/flare/FlareWebserviceClientImplFwdProxyIT.java | 2 +- .../FlareWebserviceClientImplFwdRevProxyBasicAuthIT.java | 4 ++-- .../FlareWebserviceClientImplRevProxyBasicAuthIT.java | 2 +- ...lareWebserviceClientImplRevProxyBearerTokenAuthIT.java | 2 +- .../FlareWebserviceClientImplRevProxyTlsBasicAuthIT.java | 2 +- .../FlareWebserviceClientImplRevProxyTlsClientCertIT.java | 2 +- .../flare/FlareWebserviceClientImplRevProxyTlsIT.java | 2 +- .../client/flare/FlareWebserviceClientImplTimeoutsIT.java | 2 +- .../feasibility/client/store/OAuthInterceptorIT.java | 4 ++-- .../process/feasibility/client/store/StoreClientIT.java | 8 ++++---- 14 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplBaseIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplBaseIT.java index 2246277..740b1d6 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplBaseIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplBaseIT.java @@ -12,13 +12,13 @@ public abstract class FlareWebserviceClientImplBaseIT { protected static final Network DEFAULT_CONTAINER_NETWORK = Network.newNetwork(); - public static GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.24")) + public static GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.30")) .withExposedPorts(8080) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withNetworkAliases("fhir-server") .withEnv("LOG_LEVEL", "debug"); - public static GenericContainer flare = new GenericContainer<>(DockerImageName.parse("ghcr.io/medizininformatik-initiative/flare:2.1.0")) + public static GenericContainer flare = new GenericContainer<>(DockerImageName.parse("ghcr.io/medizininformatik-initiative/flare:2.3.0")) .withExposedPorts(8080) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withNetworkAliases("flare") diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthIT.java index 61865c9..9fe86f4 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthIT.java @@ -31,7 +31,7 @@ public class FlareWebserviceClientImplFwdProxyBasicAuthIT extends FlareWebservic @Container public static GenericContainer forwardProxy = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withExposedPorts(8080) .withFileSystemBind(squidProxyConf.getPath(), "/etc/squid/squid.conf", READ_ONLY) .withFileSystemBind(passwordFile.getPath(), "/etc/squid/passwd", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT.java index fb66554..432288e 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT.java @@ -35,7 +35,7 @@ public class FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8080) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) @@ -47,7 +47,7 @@ public class FlareWebserviceClientImplFwdProxyBasicAuthRevProxyBearerTokenAuthIT .dependsOn(flare); @Container public static GenericContainer forwardProxy = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withExposedPorts(8080) .withFileSystemBind(squidProxyConf.getPath(), "/etc/squid/squid.conf", READ_ONLY) .withFileSystemBind(forwardProxyPasswordFile.getPath(), "/etc/squid/passwd", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT.java index 08950ef..848446c 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT.java @@ -37,7 +37,7 @@ public class FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT extends Fla @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8443) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) @@ -52,7 +52,7 @@ public class FlareWebserviceClientImplFwdProxyBasicAuthRevProxyTlsIT extends Fla @Container public static GenericContainer forwardProxy = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withExposedPorts(8080) .withFileSystemBind(squidProxyConf.getPath(), "/etc/squid/squid.conf", READ_ONLY) .withFileSystemBind(passwordFile.getPath(), "/etc/squid/passwd", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyIT.java index 30aed43..2545bfe 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdProxyIT.java @@ -30,7 +30,7 @@ public class FlareWebserviceClientImplFwdProxyIT extends FlareWebserviceClientIm @Container public static GenericContainer forwardProxy = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withExposedPorts(8080) .withFileSystemBind(squidProxyConf.getPath(), "/etc/squid/squid.conf", READ_ONLY) .withNetwork(DEFAULT_CONTAINER_NETWORK) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdRevProxyBasicAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdRevProxyBasicAuthIT.java index 469a143..594e120 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdRevProxyBasicAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplFwdRevProxyBasicAuthIT.java @@ -35,7 +35,7 @@ public class FlareWebserviceClientImplFwdRevProxyBasicAuthIT extends FlareWebser @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8080) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) @@ -48,7 +48,7 @@ public class FlareWebserviceClientImplFwdRevProxyBasicAuthIT extends FlareWebser .dependsOn(flare); @Container public static GenericContainer forwardProxy = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withExposedPorts(8080) .withFileSystemBind(squidProxyConf.getPath(), "/etc/squid/squid.conf", READ_ONLY) .withFileSystemBind(forwardProxyPasswordFile.getPath(), "/etc/squid/passwd", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBasicAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBasicAuthIT.java index e5ee1a8..a08745b 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBasicAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBasicAuthIT.java @@ -35,7 +35,7 @@ public class FlareWebserviceClientImplRevProxyBasicAuthIT extends FlareWebservic @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8080) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBearerTokenAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBearerTokenAuthIT.java index 521c4eb..c9a04ce 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBearerTokenAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyBearerTokenAuthIT.java @@ -34,7 +34,7 @@ public class FlareWebserviceClientImplRevProxyBearerTokenAuthIT extends FlareWeb @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8080) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsBasicAuthIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsBasicAuthIT.java index 0034c1c..b773c1f 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsBasicAuthIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsBasicAuthIT.java @@ -38,7 +38,7 @@ public class FlareWebserviceClientImplRevProxyTlsBasicAuthIT extends FlareWebser @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8443) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsClientCertIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsClientCertIT.java index f47bd5e..ec9bdf1 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsClientCertIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsClientCertIT.java @@ -36,7 +36,7 @@ public class FlareWebserviceClientImplRevProxyTlsClientCertIT extends FlareWebse @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8443) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsIT.java index a620bd4..6bbb1fc 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplRevProxyTlsIT.java @@ -35,7 +35,7 @@ public class FlareWebserviceClientImplRevProxyTlsIT extends FlareWebserviceClien @Container public static GenericContainer proxy = new GenericContainer<>( - DockerImageName.parse("nginx:1.25.1")) + DockerImageName.parse("nginx:1.27.1")) .withExposedPorts(8443) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(indexFile.getPath(), "/usr/share/nginx/html/index.html", READ_ONLY) diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplTimeoutsIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplTimeoutsIT.java index 391fefe..84b9e9e 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplTimeoutsIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/flare/FlareWebserviceClientImplTimeoutsIT.java @@ -44,7 +44,7 @@ public class FlareWebserviceClientImplTimeoutsIT extends FlareWebserviceClientIm @Autowired protected FlareWebserviceClient flareClient; @Container - public static ToxiproxyContainer toxiproxy = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.7.0") + public static ToxiproxyContainer toxiproxy = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.9.0") .withNetwork(DEFAULT_CONTAINER_NETWORK) .dependsOn(flare); private static ToxiproxyClient toxiproxyClient; diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java index 418075c..04bb6e3 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/OAuthInterceptorIT.java @@ -59,7 +59,7 @@ public class OAuthInterceptorIT { @Container public static GenericContainer forwardProxyNoAuth = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withExposedPorts(8080) .withFileSystemBind(getResource("keycloak_forward_proxy.conf").getPath(), "/etc/squid/squid.conf", @@ -67,7 +67,7 @@ public class OAuthInterceptorIT { @Container public static GenericContainer forwardProxyBasicAuth = new GenericContainer<>( - DockerImageName.parse("ubuntu/squid:6.1-23.10_edge")) + DockerImageName.parse("ubuntu/squid:6.6-24.04_edge")) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withExposedPorts(8080) .withFileSystemBind(getResource("keycloak_forward_proxy_basic_auth.conf").getPath(), diff --git a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientIT.java b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientIT.java index fdb1435..f4ce6e3 100644 --- a/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientIT.java +++ b/mii-process-feasibility/src/test/java/de/medizininformatik_initiative/process/feasibility/client/store/StoreClientIT.java @@ -53,7 +53,7 @@ public class StoreClientIT { private static final Network DEFAULT_CONTAINER_NETWORK = Network.newNetwork(); @Container - public GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.27")) + public GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.30")) .withExposedPorts(8080) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withNetworkAliases("fhir-server") @@ -201,7 +201,7 @@ public void testRequestToReverseProxyWithClientCert() throws KeyStoreException, var serverCertChain = getResource("../certs/server_cert_chain.pem"); var serverCertKey = getResource("../certs/server_cert_key.pem"); - NginxContainer nginx = new NginxContainer<>("nginx:1.25.1") + NginxContainer nginx = new NginxContainer<>("nginx:1.27.1") .withExposedPorts(80) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(staticFhirMetadata.getPath(), "/static/fhir_metadata.json", READ_ONLY) @@ -249,7 +249,7 @@ public void testRequestToReverseProxyWithCredentials() { var indexFile = getResource("index.html"); var passwordFile = getResource(".htpasswd"); - NginxContainer nginx = new NginxContainer<>("nginx:1.25.1") + NginxContainer nginx = new NginxContainer<>("nginx:1.27.1") .withExposedPorts(80) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(staticFhirMetadata.getPath(), "/static/fhir_metadata.json", READ_ONLY) @@ -282,7 +282,7 @@ public void testRequestWithForwardProxy() { var nginxConf = this.getClass().getResource("nginx.conf"); var forwardProxyConfigTemplate = getResource("forward_proxy.conf.template"); - NginxContainer nginx = new NginxContainer<>("nginx:1.25.1") + NginxContainer nginx = new NginxContainer<>("nginx:1.27.1") .withExposedPorts(80) .withFileSystemBind(nginxConf.getPath(), "/etc/nginx/nginx.conf", READ_ONLY) .withFileSystemBind(forwardProxyConfigTemplate.getPath(), "/etc/nginx/templates/default.conf.template", READ_ONLY)