From 0e1bc20a72acac2d802e4649c34fa2f88c0247c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Tue, 11 Feb 2025 08:27:19 -0600 Subject: [PATCH 1/6] ADMINAPI-1145 Admin API support for Keycloak Add appSettings parameters Add code to enable/disable ConnectController Add code to support JWT from an IDP --- .../Features/Connect/ConnectController.cs | 4 ++ .../Features/FeatureToggleAttribute.cs | 33 ++++++++++ .../Features/IFeatureToggleAttribute.cs | 14 ++++ .../Infrastructure/AdminApiEndpointBuilder.cs | 13 +++- .../SwaggerHideControllerConvention.cs | 34 ++++++++++ .../Security/SecurityExtensions.cs | 66 +++++++++++++++++-- .../WebApplicationBuilderExtensions.cs | 2 + .../EdFi.Ods.AdminApi/appsettings.Docker.json | 11 +++- .../appsettings.Docker.mssql.json | 11 +++- .../EdFi.Ods.AdminApi/appsettings.json | 10 ++- .../mssql/SingleTenant/compose-build-dev.yml | 5 ++ 11 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 Application/EdFi.Ods.AdminApi/Features/FeatureToggleAttribute.cs create mode 100644 Application/EdFi.Ods.AdminApi/Features/IFeatureToggleAttribute.cs create mode 100644 Application/EdFi.Ods.AdminApi/Infrastructure/Documentation/SwaggerHideControllerConvention.cs diff --git a/Application/EdFi.Ods.AdminApi/Features/Connect/ConnectController.cs b/Application/EdFi.Ods.AdminApi/Features/Connect/ConnectController.cs index 6447ec903..bef4fd2d1 100644 --- a/Application/EdFi.Ods.AdminApi/Features/Connect/ConnectController.cs +++ b/Application/EdFi.Ods.AdminApi/Features/Connect/ConnectController.cs @@ -3,6 +3,7 @@ // The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. // See the LICENSE and NOTICES files in the project root for more information. +using EdFi.Ods.AdminApi.Infrastructure.Documentation; using EdFi.Ods.AdminApi.Infrastructure.Security; using FluentValidation; using Microsoft.AspNetCore; @@ -17,6 +18,7 @@ namespace EdFi.Ods.AdminApi.Features.Connect; [SwaggerResponse(400, FeatureConstants.BadRequestResponseDescription)] [SwaggerResponse(500, FeatureConstants.InternalServerErrorResponseDescription)] [Route(SecurityConstants.ConnectRoute)] +[SwaggerResponse(500, FeatureConstants.InternalServerErrorResponseDescription)] public class ConnectController : Controller { @@ -33,6 +35,7 @@ public ConnectController(ITokenService tokenService, IRegisterService registerSe [Consumes("application/x-www-form-urlencoded"), Produces("application/json")] [SwaggerOperation("Registers new client", "Registers new client")] [SwaggerResponse(200, "Application registered successfully.")] + [TypeFilter(typeof(FeatureToggleAttribute), Arguments = new object[] { "AppSettings:UseSelfcontainedAuthorization" })] public async Task Register([FromForm] RegisterService.RegisterClientRequest request) { if (await _registerService.Handle(request)) @@ -46,6 +49,7 @@ public async Task Register([FromForm] RegisterService.RegisterCli [Consumes("application/x-www-form-urlencoded"), Produces("application/json")] [SwaggerOperation("Retrieves bearer token", "\nTo authenticate Swagger requests, execute using \"Authorize\" above, not \"Try It Out\" here.")] [SwaggerResponse(200, "Sign-in successful.")] + [TypeFilter(typeof(FeatureToggleAttribute), Arguments = new object[] { "AppSettings:UseSelfcontainedAuthorization" })] public async Task Token() { var request = HttpContext.GetOpenIddictServerRequest() ?? throw new ValidationException("Failed to parse token request"); diff --git a/Application/EdFi.Ods.AdminApi/Features/FeatureToggleAttribute.cs b/Application/EdFi.Ods.AdminApi/Features/FeatureToggleAttribute.cs new file mode 100644 index 000000000..43e215b52 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi/Features/FeatureToggleAttribute.cs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc; + +namespace EdFi.Ods.AdminApi.Features +{ + public class FeatureToggleAttribute : ActionFilterAttribute, IFeatureToggleAttribute + { + private readonly string _featureName; + private readonly IConfiguration _configuration; + + public FeatureToggleAttribute(string featureName, IConfiguration configuration) + { + _featureName = featureName; + _configuration = configuration; + } + + public override void OnActionExecuting(ActionExecutingContext context) + { + var isDisabled = !_configuration.GetValue(_featureName); + if (isDisabled) + { + context.Result = new NotFoundResult(); + } + base.OnActionExecuting(context); + } + } +} + diff --git a/Application/EdFi.Ods.AdminApi/Features/IFeatureToggleAttribute.cs b/Application/EdFi.Ods.AdminApi/Features/IFeatureToggleAttribute.cs new file mode 100644 index 000000000..f31ba8c3b --- /dev/null +++ b/Application/EdFi.Ods.AdminApi/Features/IFeatureToggleAttribute.cs @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using Microsoft.AspNetCore.Mvc.Filters; + +namespace EdFi.Ods.AdminApi.Features +{ + public interface IFeatureToggleAttribute + { + void OnActionExecuting(ActionExecutingContext context); + } +} \ No newline at end of file diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/AdminApiEndpointBuilder.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/AdminApiEndpointBuilder.cs index fa8729ae4..3f444cf13 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/AdminApiEndpointBuilder.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/AdminApiEndpointBuilder.cs @@ -44,6 +44,10 @@ public static AdminApiEndpointBuilder MapDelete(IEndpointRouteBuilder endpoints, => new(endpoints, HttpVerb.DELETE, route, handler); public void BuildForVersions(params AdminApiVersions.AdminApiVersion[] versions) + { + BuildForVersions(string.Empty, versions); + } + public void BuildForVersions(string authorizationPolicy, params AdminApiVersions.AdminApiVersion[] versions) { if (versions.Length == 0) throw new ArgumentException("Must register for at least 1 version"); @@ -74,7 +78,14 @@ public void BuildForVersions(params AdminApiVersions.AdminApiVersion[] versions) } else { - builder.RequireAuthorization(); + if (string.IsNullOrWhiteSpace(authorizationPolicy)) + { + builder.RequireAuthorization(authorizationPolicy); + } + else + { + builder.RequireAuthorization(); + } } builder.WithGroupName(version.ToString()); diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Documentation/SwaggerHideControllerConvention.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Documentation/SwaggerHideControllerConvention.cs new file mode 100644 index 000000000..02dd04551 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Documentation/SwaggerHideControllerConvention.cs @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using Microsoft.AspNetCore.Mvc.ApplicationModels; + +namespace EdFi.Ods.AdminApi.Infrastructure.Documentation +{ + public class SwaggerHideControllerConvention : IActionModelConvention + { + private readonly IConfiguration _configuration; + private readonly List _controllerNames; + + public SwaggerHideControllerConvention(IConfiguration configuration, List controllerNames) + { + _configuration = configuration; + _controllerNames = controllerNames; + } + + public void Apply(ActionModel action) + { + if (_controllerNames.Contains(action.Controller.ControllerType.Name)) + { + var hideController = !_configuration.GetValue("AppSettings:UseSelfcontainedAuthorization"); + + if (hideController) + { + action.ApiExplorer.IsVisible = false; + } + } + } + } +} diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs index fff879086..9ec7eaeef 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs @@ -4,6 +4,7 @@ // See the LICENSE and NOTICES files in the project root for more information. using EdFi.Ods.AdminApi.Features.Connect; +using EdFi.Ods.AdminApi.Infrastructure.Documentation; using EdFi.Ods.AdminApi.Infrastructure.ErrorHandling; using EdFi.Ods.AdminApi.Infrastructure.Extensions; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -23,7 +24,10 @@ public static void AddSecurityUsingOpenIddict( IWebHostEnvironment webHostEnvironment ) { - var issuer = configuration.Get("Authentication:IssuerUrl"); + bool useSelfContainedAuthorization = configuration.GetValue("AppSettings:UseSelfcontainedAuthorization"); + var issuer = useSelfContainedAuthorization + ? configuration.Get("Authentication:IssuerUrl") + : configuration.Get("Authentication:OIDC:Authority"); var isDockerEnvironment = configuration.Get("EnableDockerEnvironment"); //OpenIddict Server @@ -81,12 +85,15 @@ IWebHostEnvironment webHostEnvironment }); //Application Security - services. + var authenticationBuilder = services. AddAuthentication(opt => { opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(opt => + }); + if (useSelfContainedAuthorization) + { + authenticationBuilder.AddJwtBearer(opt => { opt.Authority = issuer; opt.SaveToken = true; @@ -100,17 +107,64 @@ IWebHostEnvironment webHostEnvironment }; opt.RequireHttpsMetadata = !isDockerEnvironment; }); + } + else + { + authenticationBuilder.AddJwtBearer(options => + { + var oidcIssuer = configuration.Get("Authentication:OIDC:Authority"); + if (!String.IsNullOrEmpty(oidcIssuer)) + { + var oidcValidationCallback = configuration.Get("Authentication:OIDC:EnableServerCertificateCustomValidationCallback"); + var requireHttpsMetadata = configuration.Get("Authentication:OIDC:RequireHttpsMetadata"); + options.Authority = oidcIssuer; + options.SaveToken = true; + options.RequireHttpsMetadata = requireHttpsMetadata; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateAudience = false, + ValidateIssuer = true, + ValidateIssuerSigningKey = false, + ValidIssuer = oidcIssuer, + IssuerSigningKeyResolver = (token, securityToken, kid, parameters) => + { +#pragma warning disable S4830 // Server certificates should be verified during SSL/TLS connections + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => oidcValidationCallback + }; +#pragma warning restore S4830 + // Server certificates should be verified during SSL/TLS connections + // Get public keys from keycloak + var client = new HttpClient(handler); + var response = client.GetStringAsync(oidcIssuer + "/protocol/openid-connect/certs").Result; + var keys = JsonWebKeySet.Create(response).GetSigningKeys(); + return keys; + } + }; + } + }); + } + + services.AddAuthorization(opt => { opt.DefaultPolicy = new AuthorizationPolicyBuilder() - .RequireClaim(OpenIddictConstants.Claims.Scope, SecurityConstants.Scopes.AdminApiFullAccess) + .AddAuthenticationSchemes() + .RequireAssertion(context => + context.User.HasClaim(c => c.Type == OpenIddictConstants.Claims.Scope && c.Value.Contains(SecurityConstants.Scopes.AdminApiFullAccess)) + ) .Build(); }); - + // Controllers to hide from Swagger conditionally + var controllerNamesToHide = new List { "ConnectController" }; //Security Endpoints services.AddTransient(); services.AddTransient(); - services.AddControllers(); + services.AddControllers(options => + { + options.Conventions.Add(new SwaggerHideControllerConvention(configuration, controllerNamesToHide)); + }); } public class DefaultTokenResponseHandler : IOpenIddictServerHandler diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs index bf7aa7dd8..37a692531 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs @@ -21,6 +21,8 @@ using EdFi.Ods.AdminApi.Helpers; using EdFi.Ods.AdminApi.Infrastructure.Context; using EdFi.Common.Extensions; +using System.Configuration; +using Microsoft.AspNetCore.Mvc.Filters; namespace EdFi.Ods.AdminApi.Infrastructure; diff --git a/Application/EdFi.Ods.AdminApi/appsettings.Docker.json b/Application/EdFi.Ods.AdminApi/appsettings.Docker.json index a8f5f664e..60bcfc470 100644 --- a/Application/EdFi.Ods.AdminApi/appsettings.Docker.json +++ b/Application/EdFi.Ods.AdminApi/appsettings.Docker.json @@ -4,7 +4,9 @@ "DefaultPageSizeLimit": 25, "DatabaseEngine": "PostgreSQL", "PathBase": "$ADMIN_API_VIRTUAL_NAME", - "MultiTenancy": false + "MultiTenancy": false, + "EnableAdminConsoleAPI": "$ENABLE_ADMIN_CONSOLE", + "UseSelfcontainedAuthorization": "$USE_SELF_CONTAINED_AUTH" }, "AdminConsole": { "CorsSettings": { @@ -18,7 +20,12 @@ "Authentication": { "IssuerUrl": "$ISSUER_URL", "SigningKey": "$SIGNING_KEY", - "AllowRegistration": true + "AllowRegistration": true, + "OIDC": { + "Authority": "$OIDC_AUTHORITY", + "RequireHttpsMetadata": "$OIDC_REQUIRE_METADATA", + "EnableServerCertificateCustomValidationCallback": "$OIDC_ENABLE_SERVER_CERTIFICATE" + } }, "SwaggerSettings": { "EnableSwagger": true, diff --git a/Application/EdFi.Ods.AdminApi/appsettings.Docker.mssql.json b/Application/EdFi.Ods.AdminApi/appsettings.Docker.mssql.json index 765a7b4ad..27e88de81 100644 --- a/Application/EdFi.Ods.AdminApi/appsettings.Docker.mssql.json +++ b/Application/EdFi.Ods.AdminApi/appsettings.Docker.mssql.json @@ -4,12 +4,19 @@ "DefaultPageSizeLimit": 25, "DatabaseEngine": "SqlServer", "PathBase": "$ADMIN_API_VIRTUAL_NAME", - "MultiTenancy": "$MULTITENANCY_ENABLED" + "MultiTenancy": "$MULTITENANCY_ENABLED", + "EnableAdminConsoleAPI": "$ENABLE_ADMIN_CONSOLE", + "UseSelfcontainedAuthorization": "$USE_SELF_CONTAINED_AUTH" }, "Authentication": { "IssuerUrl": "$ISSUER_URL", "SigningKey": "$SIGNING_KEY", - "AllowRegistration": true + "AllowRegistration": true, + "OIDC": { + "Authority": "$OIDC_AUTHORITY", + "RequireHttpsMetadata": "$OIDC_REQUIRE_METADATA", + "EnableServerCertificateCustomValidationCallback": "$OIDC_ENABLE_SERVER_CERTIFICATE" + } }, "SwaggerSettings": { "EnableSwagger": true, diff --git a/Application/EdFi.Ods.AdminApi/appsettings.json b/Application/EdFi.Ods.AdminApi/appsettings.json index 76201b599..2ef01da08 100644 --- a/Application/EdFi.Ods.AdminApi/appsettings.json +++ b/Application/EdFi.Ods.AdminApi/appsettings.json @@ -6,7 +6,8 @@ "DefaultPageSizeLimit": 25, "MultiTenancy": false, "PreventDuplicateApplications": false, - "EnableAdminConsoleAPI": false + "EnableAdminConsoleAPI": false, + "UseSelfcontainedAuthorization": false }, "AdminConsole": { "CorsSettings": { @@ -19,7 +20,12 @@ "Authentication": { "IssuerUrl": "", "SigningKey": "", - "AllowRegistration": false + "AllowRegistration": false, + "OIDC": { + "Authority": "https://localhost/auth/realms/myrealm", + "RequireHttpsMetadata": false, + "EnableServerCertificateCustomValidationCallback": true + } }, "SwaggerSettings": { "EnableSwagger": false, diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml b/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml index 724c55433..c6624bc97 100644 --- a/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml +++ b/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml @@ -45,6 +45,11 @@ services: SIGNING_KEY: ${SIGNING_KEY} ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "${OIDC_AUTHORITY}" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE}" depends_on: - db-admin restart: always From 0c31ae71c0ddc8b486b0336552d2d87f091adb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Tue, 11 Feb 2025 20:52:03 -0600 Subject: [PATCH 2/6] Update docker containers Update compose files to include a version that uses an IDP Update parameters --- .../Security/SecurityExtensions.cs | 3 +- .../EdFi.Ods.AdminApi/appsettings.Docker.json | 1 + .../EdFi.Ods.AdminApi/appsettings.json | 1 + Docker/Compose/mssql/.env-idp.example | 61 + .../compose-build-binaries-multi-tenant.yml | 5 + .../compose-build-dev-multi-tenant.yml | 5 + ...ompose-build-idp-binaries-multi-tenant.yml | 186 + .../compose-build-idp-dev-multi-tenant.yml | 195 + .../SingleTenant/compose-build-binaries.yml | 5 + .../mssql/SingleTenant/compose-build-dev.yml | 8 +- .../compose-build-idp-binaries.yml | 155 + .../SingleTenant/compose-build-idp-dev.yml | 155 + Docker/Compose/mssql/env.example | 19 + .../compose-build-binaries-multi-tenant.yml | 5 + .../compose-build-dev-multi-tenant.yml | 5 + ...ompose-build-idp-binaries-multi-tenant.yml | 171 + .../compose-build-idp-dev-multi-tenant.yml | 172 + .../SingleTenant/compose-build-binaries.yml | 5 + .../pgsql/SingleTenant/compose-build-dev.yml | 5 + .../compose-build-idp-binaries.yml | 141 + .../SingleTenant/compose-build-idp-dev.yml | 156 + Docker/Compose/pgsql/env-idp.example | 47 + Docker/KeyCloak/realm-and-users.json | 4013 +++++++++++++++++ Docker/Settings/gateway/Dockerfile_IDP | 12 + .../gateway/default_idp.conf.template | 53 + Docker/dev.mssql.Dockerfile | 2 +- 26 files changed, 5580 insertions(+), 6 deletions(-) create mode 100644 Docker/Compose/mssql/.env-idp.example create mode 100644 Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml create mode 100644 Docker/Compose/mssql/MultiTenant/compose-build-idp-dev-multi-tenant.yml create mode 100644 Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml create mode 100644 Docker/Compose/mssql/SingleTenant/compose-build-idp-dev.yml create mode 100644 Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml create mode 100644 Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml create mode 100644 Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml create mode 100644 Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml create mode 100644 Docker/Compose/pgsql/env-idp.example create mode 100644 Docker/KeyCloak/realm-and-users.json create mode 100644 Docker/Settings/gateway/Dockerfile_IDP create mode 100644 Docker/Settings/gateway/default_idp.conf.template diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs index 9ec7eaeef..bc9e20da0 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Security/SecurityExtensions.cs @@ -123,7 +123,7 @@ IWebHostEnvironment webHostEnvironment options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false, - ValidateIssuer = true, + ValidateIssuer = configuration.Get("Authentication:OIDC:ValidateIssuer"), ValidateIssuerSigningKey = false, ValidIssuer = oidcIssuer, IssuerSigningKeyResolver = (token, securityToken, kid, parameters) => @@ -137,6 +137,7 @@ IWebHostEnvironment webHostEnvironment // Server certificates should be verified during SSL/TLS connections // Get public keys from keycloak var client = new HttpClient(handler); + Console.WriteLine("Issuer" + oidcIssuer); var response = client.GetStringAsync(oidcIssuer + "/protocol/openid-connect/certs").Result; var keys = JsonWebKeySet.Create(response).GetSigningKeys(); return keys; diff --git a/Application/EdFi.Ods.AdminApi/appsettings.Docker.json b/Application/EdFi.Ods.AdminApi/appsettings.Docker.json index 60bcfc470..88824b31f 100644 --- a/Application/EdFi.Ods.AdminApi/appsettings.Docker.json +++ b/Application/EdFi.Ods.AdminApi/appsettings.Docker.json @@ -23,6 +23,7 @@ "AllowRegistration": true, "OIDC": { "Authority": "$OIDC_AUTHORITY", + "ValidateIssuer": false, "RequireHttpsMetadata": "$OIDC_REQUIRE_METADATA", "EnableServerCertificateCustomValidationCallback": "$OIDC_ENABLE_SERVER_CERTIFICATE" } diff --git a/Application/EdFi.Ods.AdminApi/appsettings.json b/Application/EdFi.Ods.AdminApi/appsettings.json index 2ef01da08..53e2d0065 100644 --- a/Application/EdFi.Ods.AdminApi/appsettings.json +++ b/Application/EdFi.Ods.AdminApi/appsettings.json @@ -23,6 +23,7 @@ "AllowRegistration": false, "OIDC": { "Authority": "https://localhost/auth/realms/myrealm", + "ValidateIssuer": true, "RequireHttpsMetadata": false, "EnableServerCertificateCustomValidationCallback": true } diff --git a/Docker/Compose/mssql/.env-idp.example b/Docker/Compose/mssql/.env-idp.example new file mode 100644 index 000000000..728a37b11 --- /dev/null +++ b/Docker/Compose/mssql/.env-idp.example @@ -0,0 +1,61 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Licensed to the Ed-Fi Alliance under one or more agreements. + * The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. + * See the LICENSE and NOTICES files in the project root for more information. + */ + +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + + +ADMIN_API_VIRTUAL_NAME=adminapi + +# For Authentication +AUTHORITY=http://localhost/${ADMIN_API_VIRTUAL_NAME} +ISSUER_URL=https://localhost/${ADMIN_API_VIRTUAL_NAME} +SIGNING_KEY= + +ENABLE_ADMIN_CONSOLE=true +USE_SELF_CONTAINED_AUTH=false +OIDC_REQUIRE_METADATA=false +OIDC_ENABLE_SERVER_CERTIFICATE=true + +PAGING_OFFSET=0 +PAGING_LIMIT=25 +# For MSSQL only +SQLSERVER_USER=edfi +SQLSERVER_PASSWORD=P@55w0rd +DATABASE_ENGINE_FOLDER=mssql +# For Multitenant +DEFAULT_TENANT=tenant1 + +# The following needs to be set to specify a health check test for Admin api. +# RECOMMENDED: To use the default internal Admin Api health check endpoint, set the variable as follows: +ADMIN_API_HEALTHCHECK_TEST="wget -nv -t1 --spider http://${ADMIN_API_VIRTUAL_NAME}/health || exit 1" + +# To disable the health check, remove the above and instead set the variable as follows: +# ADMIN_API_HEALTHCHECK_TEST=/bin/true +# To add a custom health check, consult the documentation at https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck + + +# IdP db keycloak +KEYCLOAK_DB_IMAGE_TAG=16.2 +KEYCLOAK_POSTGRES_DB=keycloak_db +KEYCLOAK_POSTGRES_USER=edfi +KEYCLOAK_POSTGRES_PASSWORD=P@55w0rd +# IdP keycloak +KEYCLOAK_IMAGE_TAG=26.0 +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=admin +KEYCLOAK_PORT=28080 +KEYCLOAK_VIRTUAL_NAME=keycloak +KEYCLOAK_HOSTNAME= localhost +KEYCLOAK_HOSTNAME_PORT=443 +KEYCLOAK_HOSTNAME_STRICT_BACKCHANNEL=false +KEYCLOAK_HTTP_ENABLED=true +KEYCLOAK_HOSTNAME_STRICT_HTTPS=true +KEYCLOAK_HEALTH_ENABLED=true +KEYCLOAK_ADMIN_CONSOLE_REALM=myrealm diff --git a/Docker/Compose/mssql/MultiTenant/compose-build-binaries-multi-tenant.yml b/Docker/Compose/mssql/MultiTenant/compose-build-binaries-multi-tenant.yml index 7ba2c962f..5cce330a6 100644 --- a/Docker/Compose/mssql/MultiTenant/compose-build-binaries-multi-tenant.yml +++ b/Docker/Compose/mssql/MultiTenant/compose-build-binaries-multi-tenant.yml @@ -46,6 +46,11 @@ services: AppSettings__PreventDuplicateApplications: ${PREVENT_DUPLICATE_APPLICATIONS:-false} ASPNETCORE_ENVIRONMENT: "multitenantdocker" DEFAULT_TENANT: ${DEFAULT_TENANT:-tenant1} + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/mssql/MultiTenant/compose-build-dev-multi-tenant.yml b/Docker/Compose/mssql/MultiTenant/compose-build-dev-multi-tenant.yml index 53598a97d..acc9e3f75 100644 --- a/Docker/Compose/mssql/MultiTenant/compose-build-dev-multi-tenant.yml +++ b/Docker/Compose/mssql/MultiTenant/compose-build-dev-multi-tenant.yml @@ -53,6 +53,11 @@ services: AppSettings__PreventDuplicateApplications: ${PREVENT_DUPLICATE_APPLICATIONS:-false} ASPNETCORE_ENVIRONMENT: "multitenantdocker" DEFAULT_TENANT: ${DEFAULT_TENANT:-tenant2} + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml b/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml new file mode 100644 index 000000000..d2eb4b027 --- /dev/null +++ b/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml @@ -0,0 +1,186 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi-packaged + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + context: ../../../ + dockerfile: api.mssql.Dockerfile + environment: + ADMIN_WAIT_MSSQL_HOSTS: "db-admin-tenant1 db-admin-tenant2" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_SECURITY_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + SQLSERVER_TENANT1_PORT: 1433 + SQLSERVER_TENANT2_PORT: 1433 + DATABASEENGINE: "SqlServer" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-true}" + AppSettings__PreventDuplicateApplications: ${PREVENT_DUPLICATE_APPLICATIONS:-false} + ASPNETCORE_ENVIRONMENT: "multitenantdocker" + DEFAULT_TENANT: ${DEFAULT_TENANT:-tenant1} + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + volumes: + - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json + entrypoint: ["/bin/sh"] + command: ["-c","envsubst < /app/appsettings.dockertemplate.json > /app/appsettings.multitenantdocker.json && /app/run.sh"] + depends_on: + - db-admin-tenant1 + - db-admin-tenant2 + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi-packaged + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin-tenant1: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1433:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi-tenant1:/var/lib/mssql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant1 + + db-admin-tenant2: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1434:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi-tenant2:/var/lib/mssql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant2 + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi-tenant1: + driver: local + name: vol-db-admin-adminapi-tenant1 + vol-db-admin-adminapi-tenant2: + driver: local + name: vol-db-admin-adminapi-tenant2 + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/mssql/MultiTenant/compose-build-idp-dev-multi-tenant.yml b/Docker/Compose/mssql/MultiTenant/compose-build-idp-dev-multi-tenant.yml new file mode 100644 index 000000000..e392ed60b --- /dev/null +++ b/Docker/Compose/mssql/MultiTenant/compose-build-idp-dev-multi-tenant.yml @@ -0,0 +1,195 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + ODS_VIRTUAL_NAME: "${ODS_VIRTUAL_NAME:-api}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + # Important to set the context to the root, rather than setting it to the + # EdFi.Ods.AdminApi directory, so that the Dockerfile has access to other + # C# projects. + context: ../../../ + additional_contexts: + assets: ../../../../ + args: + ASPNETCORE_ENVIRONMENT: "multitenantdocker" + dockerfile: dev.mssql.Dockerfile + environment: + ADMIN_WAIT_MSSQL_HOSTS: "db-admin-tenant1 db-admin-tenant2" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_SECURITY_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + SQLSERVER_TENANT1_PORT: 1433 + SQLSERVER_TENANT2_PORT: 1433 + DATABASEENGINE: "SqlServer" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-true}" + AppSettings__PreventDuplicateApplications: ${PREVENT_DUPLICATE_APPLICATIONS:-false} + ASPNETCORE_ENVIRONMENT: "multitenantdocker" + DEFAULT_TENANT: ${DEFAULT_TENANT:-tenant2} + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + volumes: + - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json + entrypoint: ["/bin/sh"] + command: ["-c","envsubst < /app/appsettings.dockertemplate.json > /app/appsettings.multitenantdocker.json && /app/run.sh"] + depends_on: + - db-admin-tenant1 + - db-admin-tenant2 + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin-tenant1: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1433:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi-tenant1:/var/lib/mssql/data + - ../../../Settings/dev/mssql/adminapi-test-seeddata.sql:/tmp/AdminApiScripts/MsSql/adminapi-test-seeddata.sql + restart: always + container_name: ed-fi-db-admin-adminapi-tenant1 + + db-admin-tenant2: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1434:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi-tenant2:/var/lib/mssql/data + - ../../../Settings/dev/mssql/adminapi-test-seeddata.sql:/tmp/AdminApiScripts/MsSql/adminapi-test-seeddata.sql + restart: always + container_name: ed-fi-db-admin-adminapi-tenant2 + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi-tenant1: + driver: local + name: vol-db-admin-adminapi-tenant1 + vol-db-admin-adminapi-tenant2: + driver: local + name: vol-db-admin-adminapi-tenant2 + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-binaries.yml b/Docker/Compose/mssql/SingleTenant/compose-build-binaries.yml index 55f2831c9..edc79c748 100644 --- a/Docker/Compose/mssql/SingleTenant/compose-build-binaries.yml +++ b/Docker/Compose/mssql/SingleTenant/compose-build-binaries.yml @@ -46,6 +46,11 @@ services: AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-true}" MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" depends_on: - db-admin restart: always diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml b/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml index c6624bc97..e887a2a1c 100644 --- a/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml +++ b/Docker/Compose/mssql/SingleTenant/compose-build-dev.yml @@ -46,10 +46,10 @@ services: ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} - USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} - OIDC_AUTHORITY: "${OIDC_AUTHORITY}" - OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA}" - OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE}" + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" depends_on: - db-admin restart: always diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml b/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml new file mode 100644 index 000000000..2d4788109 --- /dev/null +++ b/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi-packaged + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: api.mssql.Dockerfile + environment: + ADMIN_MSSQL_HOST: db-admin + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_SECURITY_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + DATABASEENGINE: SqlServer + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + API_INTERNAL_URL: ${API_INTERNAL_URL} + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-true}" + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + depends_on: + - db-admin + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi-packaged + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_SECURITY_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1433:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi:/var/lib/mssql/data + restart: always + container_name: ed-fi-db-admin-adminapi + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi: + driver: local + name: vol-db-admin-adminapi + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-idp-dev.yml b/Docker/Compose/mssql/SingleTenant/compose-build-idp-dev.yml new file mode 100644 index 000000000..851ee1320 --- /dev/null +++ b/Docker/Compose/mssql/SingleTenant/compose-build-idp-dev.yml @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + ODS_VIRTUAL_NAME: "${ODS_VIRTUAL_NAME:-api}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + # Important to set the context to the root, rather than setting it to the + # EdFi.Ods.AdminApi directory, so that the Dockerfile has access to other + # C# projects. + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dev.mssql.Dockerfile + environment: + ADMIN_MSSQL_HOST: db-admin + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_SECURITY_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + DATABASEENGINE: "SqlServer" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + depends_on: + - db-admin + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + + db-admin: + build: + context: ../../../Settings/DB-Admin/mssql/ + dockerfile: Dockerfile + environment: + SA_PASSWORD: "${SA_PASSWORD:-P@55w0rd}" + ACCEPT_EULA: "Y" + SQLSERVER_ADMIN_DATASOURCE: db-admin + SQLSERVER_ODS_DATASOURCE: db-admin + SQLSERVER_PORT: 1433 + SQLSERVER_USER: ${SQLSERVER_USER:-edfi} + SQLSERVER_PASSWORD: "${SQLSERVER_PASSWORD:-P@55w0rd}" + ports: + - 1433:1433 + healthcheck: + test: ["CMD", "/usr/local/bin/healthcheck.sh"] + interval: 10s + retries: 10 + volumes: + - vol-db-admin-adminapi:/var/lib/mssql/data + - ../../../Settings/dev/mssql/adminapi-test-seeddata.sql:/tmp/AdminApiScripts/MsSql/adminapi-test-seeddata.sql + restart: always + container_name: ed-fi-db-admin-adminapi + +volumes: + vol-db-admin-adminapi: + driver: local + name: vol-db-admin-adminapi + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/mssql/env.example b/Docker/Compose/mssql/env.example index 8b7343a87..a723fbbf0 100644 --- a/Docker/Compose/mssql/env.example +++ b/Docker/Compose/mssql/env.example @@ -27,3 +27,22 @@ ADMIN_API_HEALTHCHECK_TEST="wget -nv -t1 --spider http://${ADMIN_API_VIRTUAL_NAM # To disable the health check, remove the above and instead set the variable as follows: # ADMIN_API_HEALTHCHECK_TEST=/bin/true # To add a custom health check, consult the documentation at https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck + +# IdP db keycloak +KEYCLOAK_DB_IMAGE_TAG=16.2 +KEYCLOAK_POSTGRES_DB=keycloak_db +KEYCLOAK_POSTGRES_USER=edfi +KEYCLOAK_POSTGRES_PASSWORD=P@55w0rd +# IdP keycloak +KEYCLOAK_IMAGE_TAG=26.0 +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=admin +KEYCLOAK_PORT=28080 +KEYCLOAK_VIRTUAL_NAME=keycloak +KEYCLOAK_HOSTNAME= localhost +KEYCLOAK_HOSTNAME_PORT=443 +KEYCLOAK_HOSTNAME_STRICT_BACKCHANNEL=false +KEYCLOAK_HTTP_ENABLED=true +KEYCLOAK_HOSTNAME_STRICT_HTTPS=true +KEYCLOAK_HEALTH_ENABLED=true +KEYCLOAK_ADMIN_CONSOLE_REALM=myrealm diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml index a02b504f7..99b8651aa 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml @@ -41,6 +41,11 @@ services: AppSettings__MultiTenancy: "${MULTITENANCY_ENABLED:-true}" AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ASPNETCORE_ENVIRONMENT: "multitenantdocker" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml index c59f72b8a..79bd19c24 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml @@ -46,6 +46,11 @@ services: AppSettings__MultiTenancy: "${MULTITENANCY_ENABLED:-true}" AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ASPNETCORE_ENVIRONMENT: "multitenantdocker" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml new file mode 100644 index 000000000..21a4a772e --- /dev/null +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml @@ -0,0 +1,171 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi-packaged + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + context: ../../../ + dockerfile: api.pgsql.Dockerfile + environment: + POSTGRES_PORT: 5432 + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ADMIN_WAIT_POSTGRES_HOSTS: "db-admin-tenant1 db-admin-tenant2 " + DATABASEENGINE: "PostgreSql" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + AppSettings__MultiTenancy: "${MULTITENANCY_ENABLED:-true}" + AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" + ASPNETCORE_ENVIRONMENT: "multitenantdocker" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + volumes: + - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json + entrypoint: ["/bin/sh"] + command: ["-c","envsubst < /app/appsettings.dockertemplate.json > /app/appsettings.multitenantdocker.json && /app/run.sh"] + depends_on: + - db-admin-tenant1 + - db-admin-tenant2 + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi-packaged + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin-tenant1: + build: + context: ../../../Settings/DB-Admin/pgsql/ + dockerfile: Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5401:5432" + volumes: + - vol-db-admin-adminapi-tenant1:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant1 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + start_period: "60s" + retries: 3 + + db-admin-tenant2: + build: + context: ../../../Settings/DB-Admin/pgsql/ + dockerfile: Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5402:5432" + volumes: + - vol-db-admin-adminapi-tenant2:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant2 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + start_period: "60s" + retries: 3 + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi-tenant1: + driver: local + name: vol-db-admin-adminapi-tenant1 + vol-db-admin-adminapi-tenant2: + driver: local + name: vol-db-admin-adminapi-tenant2 + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml new file mode 100644 index 000000000..32bc26c97 --- /dev/null +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml @@ -0,0 +1,172 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + ODS_VIRTUAL_NAME: "${ODS_VIRTUAL_NAME:-api}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + # Important to set the context to the root, rather than setting it to the + # EdFi.Ods.AdminApi directory, so that the Dockerfile has access to other + # C# projects. + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dev.pgsql.Dockerfile + environment: + POSTGRES_PORT: 5432 + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ADMIN_WAIT_POSTGRES_HOSTS: "db-admin-tenant1 db-admin-tenant2 " + DATABASEENGINE: "PostgreSql" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + AppSettings__MultiTenancy: "${MULTITENANCY_ENABLED:-true}" + AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" + ASPNETCORE_ENVIRONMENT: "multitenantdocker" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + volumes: + - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json + entrypoint: ["/bin/sh"] + command: ["-c","envsubst < /app/appsettings.dockertemplate.json > /app/appsettings.multitenantdocker.json && /app/run.sh"] + depends_on: + - db-admin-tenant1 + - db-admin-tenant2 + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin-tenant1: + build: + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dbadmin.Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5401:5432" + volumes: + - vol-db-admin-adminapi-tenant1:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant1 + + db-admin-tenant2: + build: + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dbadmin.Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5402:5432" + volumes: + - vol-db-admin-adminapi-tenant2:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi-tenant2 + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi-tenant1: + driver: local + name: vol-db-admin-adminapi-tenant1 + vol-db-admin-adminapi-tenant2: + driver: local + name: vol-db-admin-adminapi-tenant2 + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml index 723614381..77cf754b4 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml @@ -41,6 +41,11 @@ services: AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" depends_on: - db-admin restart: always diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml index 912164761..72bf732a2 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml @@ -42,6 +42,11 @@ services: SIGNING_KEY: ${SIGNING_KEY} ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: true + OIDC_AUTHORITY: "" + OIDC_REQUIRE_METADATA: "" + OIDC_ENABLE_SERVER_CERTIFICATE: "" depends_on: - pb-admin restart: always diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml new file mode 100644 index 000000000..1b1908d05 --- /dev/null +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml @@ -0,0 +1,141 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi-packaged + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + context: ../../../ + dockerfile: api.pgsql.Dockerfile + environment: + ADMIN_POSTGRES_HOST: db-admin + POSTGRES_PORT: 5432 + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + DATABASEENGINE: "PostgreSql" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + API_INTERNAL_URL: ${API_INTERNAL_URL} + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + AppSettings__DefaultPageSizeOffset: ${PAGING_OFFSET:-0} + AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} + AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + depends_on: + - db-admin + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi-packaged + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin: + build: + context: ../../../Settings/DB-Admin/pgsql/ + dockerfile: Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5401:5432" + volumes: + - vol-db-admin-adminapi:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi: + driver: local + name: vol-db-admin-adminapi + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml new file mode 100644 index 000000000..60deb8bd2 --- /dev/null +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml @@ -0,0 +1,156 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +services: + nginx: + build: + context: ../../../Settings/gateway/ + dockerfile: Dockerfile_IDP + environment: + ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" + ODS_VIRTUAL_NAME: "${ODS_VIRTUAL_NAME:-api}" + KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} + ports: + - "443:443" + - "80:80" + container_name: ed-fi-gateway-adminapi + restart: always + hostname: nginx + volumes: + - ../../../Settings/ssl:/ssl/ + depends_on: + - adminapi + - idp-keycloak + + adminapi: + build: + # Important to set the context to the root, rather than setting it to the + # EdFi.Ods.AdminApi directory, so that the Dockerfile has access to other + # C# projects. + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dev.pgsql.Dockerfile + environment: + ADMIN_POSTGRES_HOST: pb-admin + POSTGRES_PORT: "${PGBOUNCER_LISTEN_PORT:-6432}" + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + DATABASEENGINE: "PostgreSql" + AUTHORITY: ${AUTHORITY} + ISSUER_URL: ${ISSUER_URL} + SIGNING_KEY: ${SIGNING_KEY} + ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" + ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" + depends_on: + - pb-admin + - idp-keycloak + restart: always + hostname: ${ADMIN_API_VIRTUAL_NAME:-adminapi} + container_name: adminapi + healthcheck: + test: ${ADMIN_API_HEALTHCHECK_TEST} + start_period: "60s" + retries: 3 + + db-admin: + build: + context: ../../../ + additional_contexts: + assets: ../../../../ + dockerfile: dbadmin.Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + ports: + - "5880:5432" + volumes: + - vol-db-admin-adminapi:/var/lib/postgresql/data + restart: always + container_name: ed-fi-db-admin-adminapi + + pb-admin: + image: pgbouncer/pgbouncer@sha256:aa8a38b7b33e5fe70c679053f97a8e55c74d52b00c195f0880845e52b50ce516 #pgbouncer:1.15.0 + environment: + DATABASES: "* = host = db-admin port=5432 user=${POSTGRES_USER} password=${POSTGRES_PASSWORD}" + PGBOUNCER_LISTEN_PORT: "${PGBOUNCER_LISTEN_PORT:-6432}" + ports: + - "5401:${PGBOUNCER_LISTEN_PORT:-6432}" + restart: always + container_name: ed-fi-pb-admin-adminapi + depends_on: + - db-admin + + idp-keycloak: + image: quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG:-26.0} + command: start-dev --import-realm + environment: + KC_HOSTNAME: "https://${KEYCLOAK_HOSTNAME:-localhost}/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_HTTP_ENABLED: true + KC_HTTPS_ENABLED: true + KC_HOSTNAME_STRICT: true + KC_HEALTH_ENABLED: ${KEYCLOAK_HEALTH_ENABLED:-true} + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://db-idp-keycloak/${KEYCLOAK_POSTGRES_DB:-keycloak_db} + KC_PROXY_HEADERS: forwarded + PROXY_ADDRESS_FORWARDING: true + KC_DB_USERNAME: ${KEYCLOAK_POSTGRES_USER:-edfi} + KC_DB_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + KC_HTTP_RELATIVE_PATH: "/${KEYCLOAK_RELATIVE_PATH:-auth}/" + KC_SPI_LOGIN_PROTOCOL_OPENID_CONNECT_LEGACY_IFRAME_CHECK: false + KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-OFF} + KC_LOG: console + KC_HTTPS_CERTIFICATE_FILE: /ssl/server.crt + KC_HTTPS_CERTIFICATE_KEY_FILE: /ssl/server.key + ports: + - ${KEYCLOAK_PORT:-28080}:8080 + restart: always + depends_on: + - pb-idp-keycloak + hostname: ${KEYCLOAK_VIRTUAL_NAME:-idp_keycloak} + volumes: + - ../../../Settings/ssl:/ssl/ + - ../../../KeyCloak/realm-and-users.json:/opt/keycloak/data/import/realm-and-users.json + container_name: ed-fi-keycloak + + db-idp-keycloak: + image: postgres:${KEYCLOAK_DB_IMAGE_TAG:-16.2} + volumes: + - vol-db-idp-keycloak:/var/lib/postgresql/data + environment: + POSTGRES_DB: ${KEYCLOAK_POSTGRES_DB:-keycloak_db} + POSTGRES_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + container_name: ed-fi-db-idp-keycloak + + pb-idp-keycloak: + image: bitnami/pgbouncer:1.20.0 + environment: + PGBOUNCER_DATABASE: '*' + PGBOUNCER_PORT: ${PGBOUNCER_LISTEN_PORT:-6432} + PGBOUNCER_EXTRA_FLAGS: ${PGBOUNCER_EXTRA_FLAGS} + POSTGRESQL_USER: ${KEYCLOAK_POSTGRES_USER:-edfi} + POSTGRESQL_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-P@55w0rd} + POSTGRESQL_HOST: db-idp-keycloak + PGBOUNCER_SET_DATABASE_USER: 'yes' + PGBOUNCER_SET_DATABASE_PASSWORD: 'yes' + PGBOUNCER_IGNORE_STARTUP_PARAMETERS: extra_float_digits + restart: always + container_name: ed-fi-pb-idp-keycloak + depends_on: + - db-idp-keycloak + +volumes: + vol-db-admin-adminapi: + driver: local + name: vol-db-admin-adminapi + vol-db-idp-keycloak: + driver: local + name: vol-db-idp-keycloak diff --git a/Docker/Compose/pgsql/env-idp.example b/Docker/Compose/pgsql/env-idp.example new file mode 100644 index 000000000..4daa5e319 --- /dev/null +++ b/Docker/Compose/pgsql/env-idp.example @@ -0,0 +1,47 @@ +ADMIN_API_VIRTUAL_NAME=adminapi + +# For Authentication +AUTHORITY=http://localhost/${ADMIN_API_VIRTUAL_NAME} +ISSUER_URL=https://localhost/${ADMIN_API_VIRTUAL_NAME} +SIGNING_KEY= + +PAGING_OFFSET=0 +PAGING_LIMIT=25 + +# For Postgres only +POSTGRES_USER=postgres +POSTGRES_PASSWORD=P@ssw0rd +PGBOUNCER_LISTEN_PORT=6432 + + +# For MSSQL only +MSSQL_USER=postgres +MSSQL_PASSWORD=P@ssw0rd +MSSQL_PORT=14333 + +# The following needs to be set to specify a health check test for Admin api. +# RECOMMENDED: To use the default internal Admin Api health check endpoint, set the variable as follows: +ADMIN_API_HEALTHCHECK_TEST="wget -nv -t1 --spider http://${ADMIN_API_VIRTUAL_NAME}/health || exit 1" + +# To disable the health check, remove the above and instead set the variable as follows: +# ADMIN_API_HEALTHCHECK_TEST=/bin/true +# To add a custom health check, consult the documentation at https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck + +# IdP db keycloak +KEYCLOAK_DB_IMAGE_TAG=16.2 +KEYCLOAK_POSTGRES_DB=keycloak_db +KEYCLOAK_POSTGRES_USER=edfi +KEYCLOAK_POSTGRES_PASSWORD=P@55w0rd +# IdP keycloak +KEYCLOAK_IMAGE_TAG=26.0 +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=admin +KEYCLOAK_PORT=28080 +KEYCLOAK_VIRTUAL_NAME=keycloak +KEYCLOAK_HOSTNAME= localhost +KEYCLOAK_HOSTNAME_PORT=443 +KEYCLOAK_HOSTNAME_STRICT_BACKCHANNEL=false +KEYCLOAK_HTTP_ENABLED=true +KEYCLOAK_HOSTNAME_STRICT_HTTPS=true +KEYCLOAK_HEALTH_ENABLED=true +KEYCLOAK_ADMIN_CONSOLE_REALM=myrealm diff --git a/Docker/KeyCloak/realm-and-users.json b/Docker/KeyCloak/realm-and-users.json new file mode 100644 index 000000000..8d989881f --- /dev/null +++ b/Docker/KeyCloak/realm-and-users.json @@ -0,0 +1,4013 @@ +[ { + "id" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "realm" : "master", + "displayName" : "Keycloak", + "displayNameHtml" : "
Keycloak
", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 60, + "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, + "bruteForceStrategy" : "MULTIPLE", + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "343f47e6-ca26-4581-a19f-54e0d5a91c29", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "myrealm-realm" : [ "view-identity-providers", "query-realms", "manage-authorization", "view-clients", "query-clients", "manage-identity-providers", "create-client", "impersonation", "view-events", "manage-clients", "manage-events", "view-users", "query-groups", "view-realm", "view-authorization", "manage-realm", "query-users", "manage-users" ], + "master-realm" : [ "manage-realm", "view-identity-providers", "view-events", "query-realms", "view-clients", "view-realm", "manage-events", "manage-authorization", "view-users", "query-users", "manage-identity-providers", "view-authorization", "impersonation", "query-clients", "create-client", "manage-clients", "query-groups", "manage-users" ] + } + }, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "attributes" : { } + }, { + "id" : "a2a9aa6c-c085-44e5-8408-645b9253ef6b", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "attributes" : { } + }, { + "id" : "a30754a7-a2e9-48f5-9e43-20b084c62c30", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "attributes" : { } + }, { + "id" : "e7941f28-3c51-4575-9ce9-7012b2fdcad2", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "attributes" : { } + }, { + "id" : "9e4535e4-746b-4d0f-b32c-186172ccc12b", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9", + "attributes" : { } + } ], + "client" : { + "myrealm-realm" : [ { + "id" : "35bcb9c8-4ee9-412f-b21d-26043cca36dc", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "50aa1aae-ce12-4990-93ca-399a446e4156", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "011885c3-0255-4196-8b3f-11a78f1fdba9", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "94e0da74-e473-420f-8a5d-60fdcf59496e", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "119c5706-b277-4c61-a2fc-ceba7c4da287", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "myrealm-realm" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "0a7f9d03-865a-4cdc-9da4-19c8f890a1a8", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "194a36a0-10f5-4348-90f4-301223bb40ab", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "b4db236e-dfde-4884-85b8-d5bc580add15", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "58a28594-4b32-4892-980d-2dc9fc472efd", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "a77408e7-5366-45d1-8da7-e04825cae877", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "myrealm-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "395e50b7-639f-4fb7-8b49-668c8048eac6", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "5c4ef008-b3a4-4b8d-917d-7f2d93027aab", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "ccd0de50-9203-48aa-9226-d88feb6cc0ce", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "21504df4-d3ca-4b78-b4b7-0d6dbf8519fe", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "e08b9554-3766-4d7f-9a7e-58bfdf632110", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "feb56580-733b-452d-8d9a-587c65528478", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "d245db0d-cf76-4452-a7f2-27cbc721c398", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + }, { + "id" : "ab4667e6-ec27-4023-bf1b-f88dac6ec311", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "attributes" : { } + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "4a4859ca-b83f-41b5-aa3b-afd92ef5d669", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "4eeaa5ff-f6a8-4a25-b745-77adf25fc143", + "attributes" : { } + } ], + "master-realm" : [ { + "id" : "a979d809-a9d6-4b13-91c3-299fb1c9d995", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "f1c3e9d3-e2e8-4e28-b23c-309e9d5e0dba", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-users", "query-groups" ] + } + }, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "1c579b39-01a5-4865-8abe-46b96e2d0f97", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "11137aa4-238c-4fe1-a062-db6c11ab7026", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "acdb90ac-d90a-4130-a262-11d983131cc4", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "3370dc7b-3cb8-4146-9549-32ab5b05ebc1", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "03ceae1d-0580-48f3-84b9-2064f9ae4da6", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "c4dbe34e-92be-4e8b-9d3d-b0d808332889", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "c49c1dcd-8856-4cbf-a513-008c0f6a2097", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "767d5b62-397e-4c1b-8775-842ac5c0c609", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "a01e078f-fbce-4626-b39a-8f4ec8b07e97", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "b542a5fb-f051-4e3c-bead-1d88b9a647cc", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "6a4c88cb-2158-4d69-9c18-acbae916e04a", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "e292c726-ccb3-4901-9494-bfac606d648c", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "cb3f8ebd-95a4-44d8-a22f-7db93c0a1af2", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "cd1e771c-0d88-427a-ad08-5a04f833017f", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "bad71457-1e06-452c-888b-df38a7ddc395", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + }, { + "id" : "035e20bb-0319-4cd3-b3fb-01a6c11a83d7", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "attributes" : { } + } ], + "account" : [ { + "id" : "89c6351b-b277-4e6f-94ec-d1ae4e9ccdf9", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "8a850b6f-1e20-43ac-8a53-4fab90b7364c", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "7e1468dd-b387-4293-9f9f-8dbb24e7e003", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "5c3d1f06-0bd8-49f4-8488-cc4b5aa30de6", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "f54616ed-13e7-41c4-b0c7-39ef5e1e8e64", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "570cb2db-ec31-48c3-b488-465dab26696b", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "a76a92a1-9354-4cb8-ad58-85c8cbd732fb", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + }, { + "id" : "a1ee2fed-a035-42d7-a7a3-eef5dfb8676b", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "a30754a7-a2e9-48f5-9e43-20b084c62c30", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "5d31328d-5800-4d03-8c09-2a5c3eb610b9" + }, + "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", "RS256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256", "RS256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], + "users" : [ { + "id" : "8b90051c-e2fe-4dbd-9770-3aa37eabb334", + "username" : "admin", + "emailVerified" : false, + "createdTimestamp" : 1733170004521, + "enabled" : true, + "totp" : false, + "credentials" : [ { + "id" : "308a7f18-274d-48d1-abab-a8c5813aa61c", + "type" : "password", + "createdDate" : 1733170005084, + "secretData" : "{\"value\":\"LR4Cksg/IR7swCmtolZuvanvLzw8egHgn49ayps/I+0=\",\"salt\":\"wL2mzmFO139rLdDiFTIfMA==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "admin", "default-roles-master" ], + "notBefore" : 0, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "9b179baa-6b78-4c47-bbc2-af975373cde6", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "78faa61e-ee6d-402f-8acc-a4656fd0f766", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "3e611b5e-9ac2-43e0-9700-4e17456fd005", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "bda0f7d4-ca78-4a19-9465-eaf47bdbcb6c", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "4eeaa5ff-f6a8-4a25-b745-77adf25fc143", + "clientId" : "broker", + "name" : "${client_broker}", + "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" : { + "realm_client" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "85047c38-9de2-4b2a-ae75-86a18c039701", + "clientId" : "master-realm", + "name" : "master Realm", + "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" : { + "realm_client" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "36d7d2dd-1d86-4c0b-beb1-083a4f24afcc", + "clientId" : "myrealm-realm", + "name" : "myrealm Realm", + "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" : { + "realm_client" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "ad224f93-2679-4c78-a4f6-77120786fb70", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/master/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/master/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "d4e9fc66-88bc-4483-9576-b3bd52556851", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "42bc4082-079a-46da-848b-10ca53e7fec5", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "consent.screen.text" : "${rolesScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "47efb4ab-3bca-4fa0-913f-8dba5eda29a6", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "74b975f4-52b5-4700-ad24-d4f2bfd2c210", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "bbc5b49a-5911-4ace-9d69-93b50f68de17", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + } ] + }, { + "id" : "4d04b15e-71c5-4630-871e-21443460bc33", + "name" : "basic", + "description" : "OpenID Connect scope for add all basic claims to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "6c87032a-cb8c-42de-95d9-c0f6054da04b", + "name" : "auth_time", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "AUTH_TIME", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "auth_time", + "jsonType.label" : "long" + } + }, { + "id" : "e47ad225-5ef2-4422-bf42-1520b9a01629", + "name" : "sub", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-sub-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "ae4a50f2-3eba-4eaf-94a8-fd2a462d8f74", + "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" : "7bc3d3ea-699b-49aa-9b47-774b0136bd38", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${profileScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "42e2da5e-ed5b-400f-bf58-ba70a3a66804", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "e9f7d478-dd0c-4477-ae1b-58f33445b979", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "c070c920-a388-40e8-acd3-f0a700e8f709", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "b1ccb299-1f11-43d0-b0f1-94aa27268cd9", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "long" + } + }, { + "id" : "ec75dfde-9636-4a1b-9539-7f77d249ec99", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "18bfb81c-17cc-4cf8-9da8-7ad0416eca54", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "845a8dba-5968-4087-bb02-4b0722344201", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "47ce4908-66b4-4a91-a75f-b4a400592183", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "3ef54cce-990f-4995-b50c-66ac8ef611f2", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "acbdf281-807f-43c0-a075-b22d4c871888", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "1f9c169f-0e26-4857-87a6-2cb47a4f468f", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "8af91569-c869-403e-ab7b-3a2671a63754", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "9b6538c8-3cfe-4c62-add6-a438f7d8cfc5", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "2620f651-20ca-42aa-bdee-158c243ffa0a", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + } ] + }, { + "id" : "3c49afaa-5ba9-4228-8d75-18ab3fed0714", + "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" : "eabd9454-cae2-4185-b77d-558ececa3bf1", + "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", + "userinfo.token.claim" : "true" + } + } ] + }, { + "id" : "f15a705f-949c-4490-a83f-9b58cb3b3325", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${emailScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "6f4fba01-23e7-437d-a15b-61712a200857", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "b6a3e069-6330-4465-8ca4-cebd70d02518", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "da56c2ca-db7b-47ca-8e41-37d89e50adc8", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${phoneScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "41a942e8-add4-4b2f-9529-a91c872d8d32", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "9172295f-9f94-4a87-8975-4b987aa9d46d", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "b051e380-0f37-4805-9f7c-577086786838", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "9b7a8b1e-d5c0-4380-9c89-4aac6cb11835", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "240c1a20-7e98-49ad-b837-5dc9cf5b8d93", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${addressScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "ef893c51-8225-4b45-a430-89642fc3ab71", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "introspection.token.claim" : "true", + "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" : "e5276dce-8c6e-4992-9eae-ffefe3513398", + "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", + "consent.screen.text" : "", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "3b216687-a1ac-466c-89f8-dc50903bcae0", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "274a00c0-8756-4768-baa3-2cd74f04883e", + "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" : "2b3b9f08-f8a6-48a8-86d3-61a19926ce92", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "9e3c438e-69d7-4fd3-a53e-989b19ddb3ca", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr", "basic" ], + "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ], + "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" : "ab2118e7-454a-424c-8558-abe113246b1c", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper" ] + } + }, { + "id" : "65541fe2-a21f-4e1a-bc8a-df2a84e10d60", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "0e29bfbd-a01c-4032-8471-cdd0237b4ba5", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "2b399def-c646-4e90-9cb2-c21d7707bcb3", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "6d4a8d66-c4b3-4a4a-95c8-7735918e5c76", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "4068c2c0-6951-454c-ae3a-340b0ef3994d", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper" ] + } + }, { + "id" : "71c0a1b9-583f-4e2e-b2f3-88f5125aab72", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "dc7edafa-6541-4f02-b099-f1d868313828", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "11182b4e-b577-4e58-aa51-410f38eb7a18", + "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" : "e43e47ba-ddcd-472c-b701-24fc5ca11539", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "bdeb130e-2e15-4e56-9a6b-0b5ceee73069" ], + "secret" : [ "dhzKjL1E1ghmlC15C3aojg" ], + "priority" : [ "100" ] + } + }, { + "id" : "41a21c75-c26f-4e2a-9907-7b94249a6f19", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEA0VPKItovNPstigLK/bIzXQTyIDu8rr85YrbNubWK5BtQPZdz62doN97Orhnc3ly6Yu7qBDCRZUBF6idw44+WSf8qM+DL5JufLitjVQnHSdtR+bd+HFAF6NHPdiCkKtBQEdwIzLe/KtbXxo+eBszK47XMED/IoxLGyVZtFXtf9WW4I+9t/TLCbuUKot1ii09JevfxiS5r+Hm2BLncMKJzYhtmghworsKn6YGA248MIiV9T+JBqxUUoc3Cy67kHuPBZp7Xr9Xg6CpgEKcMVZpcRpvseT7oz209K7qXWyaGug8jlD72KXzqoSCpRXtOmvZtu3eDhOEIhgjc64WSqCvd0wIDAQABAoIBAAxJldj747+Bawfp6A6CUl+IdcoMl6POV8kCoArhrDh9nfUvmb9cv5JgAtPXcs6etNYv3g7G5xIBdtkq3YaOHC1VzB1lebJ+rBZit577RvZ/6Ez3R3DUBbTH9BykB973gWu69c1Gj/Msz1e5gHY3uUUqm8Lsa5Oe+4pAB4E2T8iwx68pOdAx9b98PfvNvZcmg3A+8wEclu4AIG7Ttis8WNJ0oyWfXqms3uWTFu+FpfsWyuo6OcHlPeWYLL9zxgZfRaOrHm7G9mtpIBVx+TfHUzSGZbXrgAoydhFWsGY1X8Z//g4NLnKSGAE/iHsozVpS5XIAwre3ogSv3Xal5L4QkZkCgYEA8EcGIcfQKPChbLJ9ron18MI1LddM37oDE7W9Y4nP2jir/vcg1YVkKXMnCo/eUY0fxFVNt38q0+OVhpFK+Oub1QQGikEjCGpJliV7LJWXzZtaS6MXgXZSMuBO7kp/0EyvuSMuGzYReTbM5USznWkilA1bIij0xV5LRywVGJJFM/8CgYEA3wZO+w/NV5VsLayEE8Vzhrh4BHB+dYNEfxvvseJYru9xj3PsMzeB/bvk6LaF+Sb4re5Tl6wU2xKYK7/pgpTREpYM8yMksRJwBytAMVnkrfSMm/UmaH/eRETZRy8Cz/0xVFh+sD7Hke7qk0/zPst21dPDB0qZCBu0ICDFfvI2Ri0CgYEAsH+rnHLXkMs5+MugkO6cr68pOzQ1Lv7HtdnBdfXMrgMFLPRBtTcYHW6OFi8aYxNka2cyAIG0ZxN9Se0+gl0oCjC70SEJ5+uThGyh710vtoPQr1DtOlc9CExHDrnA67T5O+kAvFJaQY0ks6Fkw1NwaArrj8tACh868twJ3xPLK+cCgYAmbHTRBmDvVPwFRnKe4WbM8B0lTqhK4Km9aHe8Yu26feBHwcYQ8OBBccy3VzLvwQoZFTVrrScOsz5qUy8M40y98gIbJZPdufp5EbeGiSE/4yESgYLzgAwwINh6Thwi71E/Ydu5y6cgelQJuz2CNRWtM0WnjO+emP9Ihbzg6SP2pQKBgAvUxhuMK6GHb2lhIgeO6Vh7REho1DeBvHj6OdwW/udI3wpPbaSG9FJuujdpVw2SeptNag61A9LY/oZ8y7Qt9oj4xrdKPAnqpwYmNnCQTHcxW+Eo5Uuj8gzpmhWnkaaEigVpLzRUubEfbYQIh3qjAKREK7SIP8U+gMapCA1j8mKa" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICmzCCAYMCBgGTiPt5OzANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQxMjAyMjAwNTAyWhcNMzQxMjAyMjAwNjQyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRU8oi2i80+y2KAsr9sjNdBPIgO7yuvzlits25tYrkG1A9l3PrZ2g33s6uGdzeXLpi7uoEMJFlQEXqJ3Djj5ZJ/yoz4Mvkm58uK2NVCcdJ21H5t34cUAXo0c92IKQq0FAR3AjMt78q1tfGj54GzMrjtcwQP8ijEsbJVm0Ve1/1Zbgj7239MsJu5Qqi3WKLT0l69/GJLmv4ebYEudwwonNiG2aCHCiuwqfpgYDbjwwiJX1P4kGrFRShzcLLruQe48Fmntev1eDoKmAQpwxVmlxGm+x5PujPbT0rupdbJoa6DyOUPvYpfOqhIKlFe06a9m27d4OE4QiGCNzrhZKoK93TAgMBAAEwDQYJKoZIhvcNAQELBQADggEBALQxHVCn5pF54RKol6QJzxj+JSRRubhjF7TkknvzZe/YF0KT0EHX7OSHoleSu8Xan/4O7GMrCjU96u8sy7vzRJgDMRHIL3cQzFm4+p+faUqer8PxsnMI/B9QtWNYdJcfFp+UUUdlI0ChEU2NBIede/9eIr5jlEf+2MLl73dn7tjpugwqoH9db4ovDK6wRJyaR6xr1lJumqRWcqS4uU85nIAAvrfHESQYrYhh+AZnwtObs4Lwt65v9RlekoIv3B6z4mnfK56gpQoaTsuImPLr/9aKHmI1MuYUcLpj8N3c92TL1JyJ2ZPQkpIwML3aq93P/nt7TS3L+CwGtuDp8SdA9fw=" ], + "priority" : [ "100" ] + } + }, { + "id" : "88b6415f-5c5f-49cb-a146-8fb3c0c5f557", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEAq3kiGuBAyDVCJbhZFbRt2BNSlDqHjnJxbHBIDq7nIVMP/Ekc9MSmR2Myjx6/DPHlzUOigp85HANmvts2EunZ/TH7QzCtIJ0jP9dsQrwXsgUFjASf7T49njOFFAmz/xtOLInk3zQ2dNK2EJsNHxTngwETv0sjlIbJIRRjhJuGuOs3GlTFM6qjauCKx9zzYGW6kGuqpdhgAm3MydQZMH/KwUBOe7C3Bz3YSPsFnDs9Io1SLhxkwNsc4AKds/v1F5c2MvdbUAno+3a+CMRBY14FHCTcbxUqMdo/5rzHosQb7fJSycogukzEo9YaAgnaW1uBcRIGcE2FkBR47w+qbF70vQIDAQABAoIBACcEKP50iEkF1Uc/6wVFSLkhrGiN6MpAwA4sfjjZEz5B6CE/gZcwJ6WWrKpkFJSddex+tzuBfz0giQBkYKltDGzQMpvXN410M9ES8087/ShEfD6fzsPspZiZoG4uxwYE8ISx26Ht/3YVe9fLb/DikMr+M8ATGMVy5dDhEsPZn43zl/0zlvOrW0cg04NhDsxZZvu3oD0sRmp9WxoAstUs0yyYnb4cQXKF47I32YyQYWGxdnvI0LGTFG8MT6PmxMlMG1tamk9fLQRur0UpEnzrMKojWctLsTyQcRi8XZBlLC9s/3s5NNtgxkOZFuUbPfKvStaFfySm7N0RBSg9zWy8IAECgYEA0obS1X5ZE6oBmv/7vhI20+vq0WmP6ZNPABJulXJmRbsBVNmUMcZ7Kk3sfYlbfMTtTuK+oL9DacPqKo2DTh/bbl4svaJYFTHYdIuMZU51Y6QN0EsWgwT0bZNONnU5uXdejUL7QM6LOOwOPilJpCPh4Gl4e8uEYIyiI62xNbW9V10CgYEA0ILT/mqRB769hJWI/8mlx4QdfAmHBxLDgrOfhqnHha/Lbs4ptnD6VR7XZNbS4HerrwP2RcAnhx/tn16rl9v5xydeBVXo0y0gJXC254PrJPLNXb5FB7hnyNRMrG04CjZraaSZT6LeoiqbdJlDdJquaOVCXxIA4NMjvKZmUwWTHOECgYA7izaGe73l+eeKV2x0TeKD/e3kXN7/SVLGym/MhRa4EjRGM2Pe0Cx1wqRovTjLCUe1UBxqiq4ec/L/JhdFOW1uweQVnp0bIYX/MJj87jv1eqkNiK9NT1FyzH8KmA1Dj6eGfLNjmQd3igxdOIBDlIKGXk5ddSpzxFL3lGDSuBxdYQKBgAr5+CL6hSv9NIjYPmAIw3tfTxYKglsy96vXvNwf7+rvuCvbGoMKK4Nzni8mx+8dHaKW+M3vMaWBXsb2+t2BrQJ45hAt15XWWEzgRCCn5ycIyRrYO1YOtRfzZR3mmf6fosPq8E8q6cFrsMdQkiZ/RhMrjnTmw7kSJF13/Qb90iLBAoGBAL7F84OWkuRzZJedDiOezzT+gX7xINIGiR42BgaB0z2kav6hdBDdQv6u1ozOivGF1AmSOaj+/MkTc8jY9qOsRJO5hU+EMqaKmtfha7aD/f8j1hpe/HcAXWvcC0VKiL8YLolaYEhzgsAif+MugFrj2j572N9Yn2N44hecuKk1JrHd" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICmzCCAYMCBgGTiPt68TANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQxMjAyMjAwNTAyWhcNMzQxMjAyMjAwNjQyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCreSIa4EDINUIluFkVtG3YE1KUOoeOcnFscEgOruchUw/8SRz0xKZHYzKPHr8M8eXNQ6KCnzkcA2a+2zYS6dn9MftDMK0gnSM/12xCvBeyBQWMBJ/tPj2eM4UUCbP/G04sieTfNDZ00rYQmw0fFOeDARO/SyOUhskhFGOEm4a46zcaVMUzqqNq4IrH3PNgZbqQa6ql2GACbczJ1Bkwf8rBQE57sLcHPdhI+wWcOz0ijVIuHGTA2xzgAp2z+/UXlzYy91tQCej7dr4IxEFjXgUcJNxvFSox2j/mvMeixBvt8lLJyiC6TMSj1hoCCdpbW4FxEgZwTYWQFHjvD6psXvS9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHJH1uAXRq4rGNdbsa+A/87WZ/GDksZk24HKeLTrXVh7pNIVHq6z7JTchNnUEDOYiAgcpGNQ/hJDam2TFJL36gkm1+kb29rzMydMueyDQxUyt68oTgE+fBqJYpEZLctF6NDRHD+cF+65i+PZ4jNmy7vHNYRRDvb946bTENqmkf4Gu5LCeAeqO/Hry5yX9X0l0y4Cy5iklipf1lffU9Hxd5hHQfncWEBPxY2FoiaIS4Zdo/V9iF7Idg+MWBqr/HThF3Yh0q8uupK0TMZZWbAKvUsn3tYKRu2zCQboH0+dLq2WRpbP35JhckSpG/GfdN2vGpny1hkSVtV2GFq4L+VEaoo=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "7d134fa1-564a-4e7a-ad2c-7cd143826c76", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "0c75f580-34a5-47f4-9fae-a63d72a4edcd" ], + "secret" : [ "2jHRcN7TFNWpDv6U_6zK0c7wm9qyqvE-aujzmupFGrq3wNNzQv24sj1WBLVvQPzezNBGiWtRcFxidajiW2KaOMjZn3GLtWHdDKRlidOcHjCitkIbOoPezXd8lVTdaX6aHTzC-jBg3oZBVLDiDEPUeTzJrI79PJs0csoAQ3rjbmc" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "7a115e60-3af5-4676-b219-374a25ff8570", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "3fa23313-9eb5-4d59-9011-aabeeec9e1b3" ], + "secret" : [ "SCR1qxE_vLMrZ-pvQmlFnZl6RAL14SzD84ggu5Fg9_BJe6wr8p-NHWlkArw3o0VpK5N8eYkOTsH_ZFpxn4rwrGX5p4zCksafB3hsbPy_6gliL7yg9OPhEjh9ShSeTuxp8EuPq_LxTpmT8ginlgPNXFzihNzQ0CXB7PZ-z-ilJ2g" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "6c80b500-9c8c-40d8-81f5-2772a57d2be4", + "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" : "d03c21a3-1788-4033-920c-5b651ccdafca", + "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" : "9f7adaa3-e938-4f12-80cc-1d886c2b2b61", + "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" : "d60d801b-10d0-4783-a081-8c4d2fb21169", + "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" : "e3a946f2-d9c3-4ed9-b9f8-46e93cb29321", + "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" : "31c27f94-254a-4cc2-ae6e-8d60a448d690", + "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" : "583be0c0-7b46-4290-addb-9efbd0a7d455", + "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" : "3c338291-f939-4424-a381-6101a5ba6559", + "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" : "1ed25189-00dc-447d-9832-260cefb704ee", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "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" : "64869c33-05f4-4c0c-be1c-f99201fc208c", + "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" : "0231cd45-7961-4b05-a33e-e40b9c9ea899", + "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" : "a0d856aa-d1d7-493b-be46-b6044388c5cf", + "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" : "afe04109-aa95-4b5c-8b1d-21be5dd5d2f4", + "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" : "913577ea-c6e5-4c86-8a2b-a01cdcca8421", + "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" : "ef262c93-7529-411e-a67c-a413cd20ab4e", + "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" : "0bf59a92-c2cb-4711-8371-f6bea74445b6", + "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 + }, { + "authenticator" : "registration-terms-and-conditions", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 70, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "d677ee20-e507-4bbf-9d82-d8f2d3b50683", + "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" : "3d083d47-e4c0-4779-af6a-3dd9f8194f10", + "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" : "b6c15c63-288f-4b4c-a5c8-8fbf66da935f", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "cd63e771-4fd3-4942-bb7e-c5cc10c5506f", + "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" : "webauthn-register", + "name" : "Webauthn Register", + "providerId" : "webauthn-register", + "enabled" : true, + "defaultAction" : false, + "priority" : 70, + "config" : { } + }, { + "alias" : "webauthn-register-passwordless", + "name" : "Webauthn Register Passwordless", + "providerId" : "webauthn-register-passwordless", + "enabled" : true, + "defaultAction" : false, + "priority" : 80, + "config" : { } + }, { + "alias" : "delete_credential", + "name" : "Delete Credential", + "providerId" : "delete_credential", + "enabled" : true, + "defaultAction" : false, + "priority" : 100, + "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", + "cibaAuthRequestedUserHint" : "login_hint", + "clientOfflineSessionMaxLifespan" : "0", + "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", + "clientOfflineSessionIdleTimeout" : "0", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false", + "cibaExpiresIn" : "120", + "oauth2DeviceCodeLifespan" : "600", + "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "organizationsEnabled" : "false" + }, + "keycloakVersion" : "26.0.7", + "userManagedAccessAllowed" : false, + "organizationsEnabled" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +}, { + "id" : "debc13fa-cc4a-48a4-adc7-64790f086ba8", + "realm" : "myrealm", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 300, + "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, + "bruteForceStrategy" : "MULTIPLE", + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "4df7ceb1-8013-404e-a3be-b1549b1cefbe", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "debc13fa-cc4a-48a4-adc7-64790f086ba8", + "attributes" : { } + }, { + "id" : "299c058e-116f-4259-96d8-83ba720b3411", + "name" : "default-roles-myrealm", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "manage-account", "view-profile" ] + } + }, + "clientRole" : false, + "containerId" : "debc13fa-cc4a-48a4-adc7-64790f086ba8", + "attributes" : { } + }, { + "id" : "91d0a7da-fcf5-4a4d-996b-9049c7524a15", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "debc13fa-cc4a-48a4-adc7-64790f086ba8", + "attributes" : { } + } ], + "client" : { + "ac" : [ ], + "realm-management" : [ { + "id" : "9cd73fd8-d11d-4710-98b1-8d1b26547ca6", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "6955de36-5365-43c4-9fb0-3f6b9d97baf8", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "06e2e1a2-e404-47ae-9b86-a6ec39a1643d", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "7b0d057d-48c8-4895-b6fc-92ee25bb28d8", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "c813ce66-9520-4807-8c13-4547918923bf", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "3ed2f7f4-6dc2-486f-a0c7-5042464ac168", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "9cdd3480-62dc-4fe8-b058-bee4893ad19b", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "f7965c95-4491-448d-a05f-d77af723e495", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "5141373e-a181-47a3-a3f8-f912f1f8f9aa", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "89441521-dc71-4561-96a4-fdb9fce33720", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "86145a1e-c0d8-4433-8e64-501d89c2ecb5", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "view-identity-providers", "manage-identity-providers", "manage-clients", "create-client", "view-clients", "impersonation", "view-users", "query-realms", "query-clients", "manage-users", "view-realm", "manage-events", "manage-realm", "query-groups", "view-authorization", "manage-authorization", "view-events", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "f34b7003-4c25-4917-bb48-a2ee877a52ef", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "490a9208-0e8b-4a30-a20b-fb8ab762866a", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "283625c7-6545-457b-8511-37eb245fb9b2", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "89ec6a42-a019-4755-ab6f-09a301521f4e", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "e2c81fc1-1583-4600-834c-9ddeea0f8337", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "a10f85d2-dbc7-460e-85ed-1c9d077a80bb", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "c5c976a1-c0c6-42b7-b5cf-25b6029150c2", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + }, { + "id" : "000adf7f-d6c4-4655-8b94-88d2853bdd70", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "attributes" : { } + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "05f26654-83b2-4828-a7c9-40b992a91526", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "e529f56a-9649-4159-a7d3-5c0e6fe8bde1", + "attributes" : { } + } ], + "account" : [ { + "id" : "b70f3f9c-a888-458e-8c9b-d256f2367c66", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "8a5773f6-8f7d-4e71-a670-42a923432862", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "4b5e4bec-6a91-4fbf-9fa5-a3570cac4c14", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "17aae21c-edc1-4e27-b07e-f7e092b334d7", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "1f825d49-d8db-433c-8c55-8f7fd724e43e", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "a9b6b14d-d0f7-4eee-b496-842e8cfef269", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "05272454-81de-45ce-9d72-2caa91b241a0", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + }, { + "id" : "350b6f17-ff6f-48f1-9093-a1d74f5b7c8d", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "299c058e-116f-4259-96d8-83ba720b3411", + "name" : "default-roles-myrealm", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "debc13fa-cc4a-48a4-adc7-64790f086ba8" + }, + "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" : "77c5e18f-6987-41c3-ae9f-b6c9135d8479", + "username" : "myuser", + "firstName" : "ACUser", + "lastName" : "ACUser", + "emailVerified" : false, + "createdTimestamp" : 1728914120740, + "enabled" : true, + "totp" : false, + "credentials" : [ { + "id" : "6b65b312-5a34-443d-94dc-4a100604eb84", + "type" : "password", + "userLabel" : "My password", + "createdDate" : 1734464595279, + "secretData" : "{\"value\":\"Wesi0Gq/rYCKcNxQleoddBSAXIKY54nIo53qzsntoYk=\",\"salt\":\"RdEp32ADELJCPlTjQChf3A==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-myrealm" ], + "notBefore" : 0, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "clientScope" : "edfi_admin_api/full_access", + "roles" : [ "default-roles-myrealm" ] + }, { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + }, { + "clientScope" : "edfiadmin/full-access", + "roles" : [ "default-roles-myrealm" ] + }, { + "clientScope" : "openid", + "roles" : [ "default-roles-myrealm" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "7ad9909d-cf22-49c2-a29c-e496687fcd84", + "clientId" : "ac", + "name" : "", + "description" : "", + "rootUrl" : "https://localhost/edficonsole/v2.3/v7.2/ds4/saas/tx/", + "adminUrl" : "https://localhost/edficonsole/v2.3/v7.2/ds4/saas/tx/", + "baseUrl" : "", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "https://localhost/edficonsole/v2.3/v7.2/ds4/saas/tx/callback" ], + "webOrigins" : [ "https://localhost/edficonsole/v2.3/v7.2/ds4/saas/tx/", "*" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : true, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "oidc.ciba.grant.enabled" : "false", + "backchannel.logout.session.required" : "true", + "post.logout.redirect.uris" : "+", + "oauth2.device.authorization.grant.enabled" : "false", + "backchannel.logout.revoke.offline.tokens" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "defaultClientScopes" : [ "web-origins", "acr", "openid", "profile", "roles", "edfi_admin_api/full_access", "edfiadmin/full-access", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "08c22c00-7900-44c1-9ac5-979ad89b084e", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/myrealm/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/myrealm/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "ac159a7c-a83c-4d32-b6ba-b7f6672a8ee5", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/myrealm/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/myrealm/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "b16eba4d-a35d-423e-80b8-eb8f2c75b982", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "f34766c2-61c9-4054-af53-00ce8c7410c4", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "e529f56a-9649-4159-a7d3-5c0e6fe8bde1", + "clientId" : "broker", + "name" : "${client_broker}", + "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" : { + "realm_client" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "c877679f-d2b1-439e-bc6a-90654b73b3dd", + "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" : { + "realm_client" : "true", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "d97bcd7f-22f3-470b-83ff-dc1bf4ab5b51", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/myrealm/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/myrealm/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "286bd54b-d8ec-418b-9f51-b5f458515c08", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "ff915e21-25d7-42af-9876-cd6fd4106930", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "64b7380e-ff4e-459e-b588-cbe1b0f04e02", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "42db2eb7-2dee-4898-831c-2551b9e2470b", + "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" : "783ad193-6e07-4d69-b280-e60e361a95e0", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + }, { + "id" : "70aaea8d-b950-4e0c-8e84-2a4902c2825e", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "deac865d-fc1c-470c-85db-802748ad2c67", + "name" : "edfi_admin_api/full_access", + "description" : "edfi_admin_api/full_access", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false", + "gui.order" : "", + "consent.screen.text" : "" + } + }, { + "id" : "60de541b-be5e-411b-9173-4a3de9bccea2", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${profileScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "7052aadc-3580-4926-be93-aa076bb2eb31", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "5afbee26-c385-41f8-b262-1e8c4a07b7d7", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "ca478946-33f5-4cfb-9be1-d576fe63868a", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "58065198-809e-4eff-84b5-bb9804c890dc", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "ead56ed3-cb13-46ee-9039-d3047de85f99", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "ec8773b2-840d-4458-8ba0-47208003b776", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "21812c29-9acb-4bcc-b913-c510496dbbe2", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "2e5e68d4-7072-4954-86ed-277998d56d3b", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "4a5a16ba-16f6-4580-a833-8e6ad2f815fa", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "0753eacf-6a07-451f-a1be-b04889954bea", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "aaab2ff8-6a9f-4713-9937-4fa00f546568", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "623c6735-6265-4d4e-9383-074d6b51abcd", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "96fa7661-e887-4a66-b280-8c20a1d34e41", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "1936fb1d-82ad-487a-a7b1-ef4c66737947", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "long" + } + } ] + }, { + "id" : "432a0300-16b7-42ad-a87c-4d36626f102f", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${addressScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "81185ef8-a6dd-4b61-8e22-761606bdbef2", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "introspection.token.claim" : "true", + "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" : "208d8414-bdd8-4112-ac14-9d5aa8afaff3", + "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" : "128c0d70-091d-4b4c-9c17-e1957361d749", + "name" : "basic", + "description" : "OpenID Connect scope for add all basic claims to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "0bf6d668-0af2-48be-97f2-ac424be23498", + "name" : "auth_time", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "AUTH_TIME", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "auth_time", + "jsonType.label" : "long" + } + }, { + "id" : "3705ba60-e4bd-4ce2-91cf-feeb9717479b", + "name" : "sub", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-sub-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "33621ec9-698f-4916-994c-bf42aaf6fdd6", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${emailScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "32166696-5142-41f4-ae38-1cd248bc87d7", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "f067d153-6826-4f8c-a5b0-f156da745dd8", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + } ] + }, { + "id" : "614976a9-fd83-432f-bfef-e044d99e9d32", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${phoneScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "2a47ea2a-a579-4846-8228-71dacef7489f", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "fdb01de8-a9bd-4b61-aa76-54e131c326e7", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "bc0101c8-3d9e-4569-ba15-3786c7eed809", + "name" : "edfiadmin/full-access", + "description" : "edfi_admin_api/full_access", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false", + "gui.order" : "", + "consent.screen.text" : "" + } + }, { + "id" : "f7982b52-1c48-4223-890a-f3481b7555d3", + "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", + "consent.screen.text" : "", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "51767126-96ab-49c9-bb8c-d2410a77f9fc", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "b5774fa9-0652-404b-a4ac-091e9dc9d1c7", + "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" : "2aa1dc55-7b70-47b1-84e9-a1cd75d149be", + "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", + "userinfo.token.claim" : "true" + } + } ] + }, { + "id" : "b37af7b6-1f23-43b5-b11f-cc6372ea04da", + "name" : "openid", + "description" : "", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false", + "gui.order" : "", + "consent.screen.text" : "" + } + }, { + "id" : "fb7f4864-7581-4935-a454-d389972b3d8b", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "consent.screen.text" : "${rolesScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "81d1637b-f15e-4a1e-9f9b-048633ce1293", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "3171a93e-2d1f-4b62-850d-34729883d2f5", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "f4eb8f3e-1168-4eb8-98d5-ae83d5b31fab", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr", "basic", "openid", "edfiadmin/full-access", "edfi_admin_api/full_access" ], + "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ], + "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" : "5fa87355-e5ac-4a94-a0b4-436d360e34fa", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "a2a0c9be-d28f-420e-b2aa-22803c094992", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-user-attribute-mapper" ] + } + }, { + "id" : "930f2347-f515-4bf8-9b03-1f3672b0018f", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper" ] + } + }, { + "id" : "a7119215-57a8-46dc-a20e-9b0f31d4dfd5", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "29d0f4a2-6251-4b29-bcc8-ba55e0a15429", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "e5239dbc-6b50-434e-99cf-5b44f1859ce3", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "a64d28c3-20d9-4cef-9089-d11e2a48572f", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "fc682d3a-9936-471d-8feb-6c998ab1f1d1", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "c451603c-8370-48db-a60b-2514850467e9", + "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" : "27398153-5b63-4e94-911e-68ff2ff1b1f6", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "67ec4ad5-5d86-4033-b9a1-ad9a1f53706c" ], + "secret" : [ "VKzPeq9CgPbt4xiUV3L3VA" ], + "priority" : [ "100" ] + } + }, { + "id" : "9d13b713-1f4e-4f10-8e5d-a485cbeb2f94", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAzmga2JS3mIhyuhatxkNjk8BP+GY9f0SfevhdsBlTJnfCeCHmhnalYXtNBXq74cPtItLfxmVx3TE4p69xggUegDUhgI6dBInmEUw4qot42bihSghrB9r0AkR2DVyhPBoaWaMp4MFHwGXS7YFWpIwNdf2H2+8QCQXfW2bqQ3pPbiObCVFJn+jZh8p0jcZuK+1oOApDbsqGXs8rcC+qIkEs4Cp52SgsEuJbFYVLb93HT+f8JyGbFCIDSRt7YakgRfe24jXF94eEv0ln3MfWnpu+Expe1U7Pvpcm7pOM6wrvX8MxIiObki2wkp+TXcnydi22Au1Wl1u/Pj116wDDh4aMCQIDAQABAoIBABl/gtF+ja+qK4IRiyYS7Rozh62H89DlCU6HoAtBFaSK5tswVOoHfiastLcYkl0xdvn2Uu6PWaGZkwYkBkGpoDr2VU0sUPlej61TXSy0ThmXVVVv9Mjjo4EkM/EyoDhsgRTRszqwpcx+x6/PaoSpSIBq8X2Z6sEymIUSEZ6EXYudYZ0zNKMTRKw8Q62MkZnR/vWK40QOLpe6/esoZ6Nf8NrjWIa8bpgxVQblzKG95uz0MrJNSMcP0lX/eyIRQly2ndpQ5ECYoCq9Jh8GBQpO1a7WHgy4wyuC5OGuj+Mrqwq4C+XN+nOvHHXotp+ohDfHwCFj9AqgNyrPjeYIHHNchoECgYEA6NIG81o0vmcbEPmM7dNjOAz9VULtUzAs7jopMUUWz1FilsgwMB8HWJe52eS0mHyiyaHcvXHzPNnXpljMtbdB7NXbNXv9F12Vz6XgPM8x1TJX/qMm9DOHc8iMxjHzkhC0bN63nN3yYlBxPrAzDbhmAd0FgnYkge7g5z71bKlY8KsCgYEA4vTcfgrEDPo0c3Va62aXkhR6cDp9fuJw/EH3tjb7Lin31533T0jal3rsN6EWsgYEcxLuAGe6nsnEzuodCPowZVbD18WBS+JK1xIYCp86WkeYe20iS7lqP6bt76YBqoOTneF3HgTgvWd0w7e8Na45SZ0s+Bh6+i3B+T8UXhgTfhsCgYEAvJwJDXPybp1Qi/vec3xgULQVNtE1OcM5YvSzEjsKM4GXANfEUfeRF/Aym5Zvx2iQ6A+8p6x8hLtlvFkL3dpMCfVl1HpRmnAyQTn74sdnc3OJXbwGfqaQAPhjMtycmaP2xovW67nR9lt8onBTq7XKzY+kOwBCqxA+GpgicpjueGkCgYEAsHq5LeWPN4wj1xgNX/kBqZz07Gn/Bfhs5SsixPUR8n6981MpaOR83ce/AS7pJ/tX4Gd63KPMUQcSW9deRonNsi960EELXoeTrJOsUC4qwOLlZiyhu4JtZRuX738F0qLH2b/l0Vj3rTBScpJf7toQP/bRbgYTMpD8QaVUYCqWlbsCgYBxs8XlPwH/gBMC2iIG7FsCD0gLInjdSY9ZqAwvKbLWCr9TD1vg/9OcthDCL7jYqlTNQbpYoFsrw3FXQTfswljEI9HKdX5SBf4GP5DlDU6npsalXQv+s/KUBPUCkLXbxcbqVZuPQkzzzjH7cKO0LREGkbDmnH/jx5dALYv9sq9dLw==" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICnTCCAYUCBgGSi09rqDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTAxNDEzNTMxMFoXDTM0MTAxNDEzNTQ1MFowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5oGtiUt5iIcroWrcZDY5PAT/hmPX9En3r4XbAZUyZ3wngh5oZ2pWF7TQV6u+HD7SLS38Zlcd0xOKevcYIFHoA1IYCOnQSJ5hFMOKqLeNm4oUoIawfa9AJEdg1coTwaGlmjKeDBR8Bl0u2BVqSMDXX9h9vvEAkF31tm6kN6T24jmwlRSZ/o2YfKdI3GbivtaDgKQ27Khl7PK3AvqiJBLOAqedkoLBLiWxWFS2/dx0/n/CchmxQiA0kbe2GpIEX3tuI1xfeHhL9JZ9zH1p6bvhMaXtVOz76XJu6TjOsK71/DMSIjm5ItsJKfk13J8nYttgLtVpdbvz49desAw4eGjAkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAHd62HzHI3eCrFOC/LD+HVyNF2Y9a29nSXSJaLZPwSXNOYsMD8osGqhG2RzOpQJUjxU9VG4eOgOQRAqQNIuSB9lOILE2vfvPbiHhjOsaCdcYOBu3Ow66qUm59aAXxLCh4zWoRSOg7fJdLLk6txQIorru+KkB9oKjuPNbwhU7WqwjBK72TJVqm9UuFUQCHfiVXqw4HdH2mbwWK9a8erG1M/CLLjqRa0opS0vQCCoDqD+pudCZDe4t9J7KLIi+IiJkJy5KBW4Z5BVwdxyWQ+AFp5Ud0igwdwOogz3VxHE5jPvHE/PWsYE+M/54X/w+BNIdKGmfeqhw6CS0DwpdNffGokQ==" ], + "priority" : [ "100" ] + } + }, { + "id" : "c86b780c-8a4b-4997-9322-f78d30f135d3", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "d54bf242-06ed-4cf8-95b4-38cebfa7f70e" ], + "secret" : [ "RyLed5-HgmVvlOrYYn3ThPI95PKSxN15iWTvqpylNusQTQhz5N-cTEpzFuk7KZCo1--Q6oFsNM5MbwkE0SPCMzZfgGwJ1oOzf8WOl9l8UPhxjgbMTkyR-ebgUCiG9TYPCA9nLi8vp4K-M0yxk-NGqlK3EzkZrVXJUITvoPk0S4Y" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "9e3c42da-e459-477c-acef-ee02693126fc", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEAsaJP5TeFYADnZxpa5SPabDm8KqYmQaxFYLa7Ecps3FRBcTz8isJ/OdYTb2un1fvMttG5b9tgUn/kglhG+06+2SOaxntuLXjnaTlySVjCM176lnkJBCLHTSBcrzVjEUD1vPaW5rYowfGhG7KkaYJudGzJr5+PncqURYV6VwOEX/1L8Ll63tlKkZeS/+FPrKMNuUSB9HE4TyKNku8GPh7g0p2tR2ENuwi1qjKJl0/YK+hA2o6q4ON9h/kUBmgR2PL/RLa1WliBFDgYP2ecXqBgYUWfm5VZX0H66y5JPw3wsn3nrfMy8Hhyu8DmW7XdZ0pSA/dYMXMQpLo+8TlU3O95JwIDAQABAoIBABmplVlMGByyhLvEdvU7pMaV4LVYo5ZBSRSb0ZLUZ728/mdZpDJ3vuGgJ9ak+u5THlQbIGskilng2CZsknSj/7ZnCmk6U8SF/wiYoAYwqH27bwBmJANQ8vIVhs5ZLCLF+7p89XgHQQQj4F6cBFyp10NCpDCXIKxvI9SXYAFKJMmpFJ7TWaKUhkR1bNwdMSCRFnJj6T+DpGDfH4bE77JCGZ314EEwF9UF407NB2rc6njtgtQJF2sH+LxkxWdrGYYCfxOAhg4f3ERYEevL+bubVrzWzmYl6yrUrru9jrUHpu51vqjWCPbCC9o8EOZd7GmCW6wL6C9AAozgUuiEFxQmj+ECgYEA4w+Ewb0/b2ddHO3LtDaIY+W338ZCJK3SRgf+nWMJXZOTcwWLUM90icXOFINGnSaxjTVE/7U4GsdYX88PS/CpjJLcOy9ZIwBVI/N+Ic+0jQ/6GFE4WkP3nYjTTd4HQ0/KyGrzZ0cg6Sg9Hi562CZd7n/zUH/gjx7uIkiZ1y+okfUCgYEAyEYdPcij5Dkpcgb/S0WXZDB/ctMYJqa8GRf1iMhu2eAz6j+plWn2zHtdsRtF+hQH/GQubbxlTvNPpe9Nf+bhX+4bHG9oNkWFH6t3++vni0hGylHs6eNhCOeXzmzb9SR+NGPb8q7+Ib2ya2xQ5o2jPq2qlKQMPQmPHnl+uzW5ASsCgYATPvZ+wX7F/5np4NIaZWDsLsWGJzTmDQG8w+K2DnX1w5OE9VxYrizvnJ+aJ4JtwaDdGj3N+ttVkb4Q6OkgA7crXitirOG+UMHmuTXgwc1JA6isNP400HwFk1ptyDsPXo0OrdoRz/qfKLT9gO0SszXVCG1kTmKHXxTKPSMlFToRnQKBgFu2oBV3GHafJretNKQHznh3LSYsPVcV6/Wh3zMwdnMYFS4k0Ug3Kmoh5JoCX11SZwXR6uEd8VbiXYsjt13nITaJF6lB63tPAtOp9lxLf9Fs294y/kdtdTZauE4z09bDS3g6crMEKCTTdi1zgOjT2/oMFZ3UMjaRdhUClmKtC3fZAoGBANZ8vUtAukZC+bwDQ+vSvyO6kJxlV3QHxBYVleNgNzPuk/HSQOM576wDm8cok+VMTdeU8Gmrks1muRogB9GHkVyWfzr6DRbO3+RTrptprEiQ0LsQILusqVfZoFGebmv9PGV80N5hgt1qhA8j4vzYFrna2LHWedlCdxhuKX2hg1a/" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICnTCCAYUCBgGSi09s7jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTAxNDEzNTMxMVoXDTM0MTAxNDEzNTQ1MVowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGiT+U3hWAA52caWuUj2mw5vCqmJkGsRWC2uxHKbNxUQXE8/IrCfznWE29rp9X7zLbRuW/bYFJ/5IJYRvtOvtkjmsZ7bi1452k5cklYwjNe+pZ5CQQix00gXK81YxFA9bz2lua2KMHxoRuypGmCbnRsya+fj53KlEWFelcDhF/9S/C5et7ZSpGXkv/hT6yjDblEgfRxOE8ijZLvBj4e4NKdrUdhDbsItaoyiZdP2CvoQNqOquDjfYf5FAZoEdjy/0S2tVpYgRQ4GD9nnF6gYGFFn5uVWV9B+usuST8N8LJ9563zMvB4crvA5lu13WdKUgP3WDFzEKS6PvE5VNzveScCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAk1pKVeymYKOv1S4xXrf2n0REnL85/315dX1ZjFbTkSyAPKmiSN5zU5sIuaU1zFW86uIcf2IoaqpMcUdstDbGvzo1Fq0qenkMnM7Z5o1yBxLIa9b5mYTflo6nEKBhNCDRyHLsDTxgPWLhIh3njJ64KIihaON2w/6GIJ8aHlqB+tJoX9toHadRE8RcrlDrAuA8LtVwEFpgITiDYiGPDhfZCxZxiddf1JdUcnMXuNWe95VcjWf0crUCiEcgUqNmdcb1vIMjtE96ugymMPb1J3RmQ8Cueby7kk0GfCvJSzDkhhfsxqgMXBqzoE75YO6vmLp3L44ccQ/F5ZMis9q60lD7Dw==" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "4dda4abd-ba7f-44f0-a03e-a06bc221d31c", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "c4c79ac7-036d-46b5-93ed-1086d9b06cf6" ], + "secret" : [ "bGeCSAMdyKCBExUpkdHg1ix9Sr9avhU9syVsmkCodfg4uVclEFod3sTmdpsN66Ox1iCVbb5BSt3q1PqMNDlEz11tMg2sGK8BFWTyXdiUWiEe1T49zNKyGBd-Hvo0iN-69Fi7F8GrXGZwoaY7qDcjM-ZE9AJNqVEjZZjWZ-2qe4k" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "f8b42759-a084-476a-b480-9750242a9f1d", + "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" : "2f1da14b-68dc-4202-beb6-7756cec39adf", + "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" : "6674803b-06d1-42f6-bbe5-17e3afab523b", + "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" : "eefc4ec5-e87b-466d-9d5f-fd0481fd4080", + "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" : "15502877-a537-4367-a5c1-2c9ff6624d24", + "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" : "6dc59805-b06f-4ee3-bedc-25fdec8bef60", + "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" : "abc0e6d4-4fbb-43c0-9801-44e269258718", + "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" : "489da63f-8ab9-4210-bcd7-1a295323e952", + "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" : "79c94038-6778-46ac-ab05-8483c32cc86f", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "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" : "0bf58859-5fc8-4994-af90-d2328a9e1980", + "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" : "29cca532-f5cb-4e8f-89fc-b4ee40f606ea", + "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" : "0327ad7e-65a9-45b3-9340-361c2c1b876f", + "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" : "2120393e-508e-43aa-9f26-f70856296236", + "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" : "f48ee6d2-3aa8-43e0-9335-e6384f3844a0", + "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" : "683d466c-08ca-4500-98d7-6974df5f585b", + "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" : "a024668b-e2c7-4d80-95b8-adaa16965ddb", + "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" : "38b9c486-d2a5-4fef-af03-ad98d96cb905", + "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" : "eaf5726d-ce9e-44f7-ba32-c495bf858932", + "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" : "941074e4-9a29-48bb-9c24-54cba2dd330a", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "15e16220-866b-4f25-ac6f-f458d95ced8b", + "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" : "webauthn-register", + "name" : "Webauthn Register", + "providerId" : "webauthn-register", + "enabled" : true, + "defaultAction" : false, + "priority" : 70, + "config" : { } + }, { + "alias" : "webauthn-register-passwordless", + "name" : "Webauthn Register Passwordless", + "providerId" : "webauthn-register-passwordless", + "enabled" : true, + "defaultAction" : false, + "priority" : 80, + "config" : { } + }, { + "alias" : "delete_credential", + "name" : "Delete Credential", + "providerId" : "delete_credential", + "enabled" : true, + "defaultAction" : false, + "priority" : 100, + "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", + "cibaAuthRequestedUserHint" : "login_hint", + "clientOfflineSessionMaxLifespan" : "0", + "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", + "clientOfflineSessionIdleTimeout" : "0", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false", + "cibaExpiresIn" : "120", + "oauth2DeviceCodeLifespan" : "600", + "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "organizationsEnabled" : "false" + }, + "keycloakVersion" : "26.0.7", + "userManagedAccessAllowed" : false, + "organizationsEnabled" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +} ] \ No newline at end of file diff --git a/Docker/Settings/gateway/Dockerfile_IDP b/Docker/Settings/gateway/Dockerfile_IDP new file mode 100644 index 000000000..597606f53 --- /dev/null +++ b/Docker/Settings/gateway/Dockerfile_IDP @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +# Tag nginx:alpine3.20 +FROM nginx@sha256:2140dad235c130ac861018a4e13a6bc8aea3a35f3a40e20c1b060d51a7efd250 +LABEL maintainer="Ed-Fi Alliance, LLC and Contributors " + +COPY ./default_idp.conf.template /etc/nginx/templates/ + +EXPOSE 443 diff --git a/Docker/Settings/gateway/default_idp.conf.template b/Docker/Settings/gateway/default_idp.conf.template new file mode 100644 index 000000000..79bcfd03c --- /dev/null +++ b/Docker/Settings/gateway/default_idp.conf.template @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: Apache-2.0 +# Licensed to the Ed-Fi Alliance under one or more agreements. +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +# See the LICENSE and NOTICES files in the project root for more information. + +server { + listen 80 default_server; + + server_name _; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name localhost; + + ssl_certificate /ssl/server.crt; + ssl_certificate_key /ssl/server.key; + + location /${ADMIN_API_VIRTUAL_NAME} { + client_max_body_size 20M; + proxy_pass http://${ADMIN_API_VIRTUAL_NAME}; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /auth { + proxy_pass http://ed-fi-keycloak:8080/auth; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header Accept-Encoding ""; + # Increase proxy timeouts + proxy_connect_timeout 60s; + proxy_read_timeout 60s; + proxy_send_timeout 60s; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization'; + add_header Content-Security-Policy "frame-src 'self' https://locahost"; + } +} diff --git a/Docker/dev.mssql.Dockerfile b/Docker/dev.mssql.Dockerfile index 7fd3f85a2..d231bc29e 100644 --- a/Docker/dev.mssql.Dockerfile +++ b/Docker/dev.mssql.Dockerfile @@ -26,7 +26,7 @@ RUN dotnet restore && dotnet build -c Release RUN dotnet publish -c Release /p:EnvironmentName=$ASPNETCORE_ENVIRONMENT --no-build -o /app/EdFi.Ods.AdminApi.AdminConsole FROM mcr.microsoft.com/dotnet/aspnet:8.0.8-alpine3.20-amd64@sha256:98fa594b91cda6cac28d2aae25567730db6f8857367fab7646bdda91bc784b5f AS runtimebase -RUN apk --upgrade --no-cache add dos2unix=~7 bash=~5 gettext=~0 icu=~74 && \ +RUN apk --upgrade --no-cache add dos2unix=~7 bash=~5 gettext=~0 icu=~74 curl && \ addgroup -S edfi && adduser -S edfi -G edfi FROM runtimebase AS setup From 5134c7c9920dd2c9b2d358fbcfafdd38358628fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Tue, 11 Feb 2025 21:19:49 -0600 Subject: [PATCH 3/6] Update documentation Update documentation Update gateway reference --- .../.automation_api_idp_mssql.env | 37 ++++++++ .../.automation_api_idp_pgsql.env | 39 ++++++++ ...ompose-build-idp-binaries-multi-tenant.yml | 2 +- .../compose-build-idp-dev-multi-tenant.yml | 2 +- docs/developer.md | 90 +++++++++++-------- docs/docker.md | 8 +- 6 files changed, 138 insertions(+), 40 deletions(-) create mode 100644 Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_mssql.env create mode 100644 Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_pgsql.env diff --git a/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_mssql.env b/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_mssql.env new file mode 100644 index 000000000..549aa6daf --- /dev/null +++ b/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_mssql.env @@ -0,0 +1,37 @@ +API_MODE=SharedInstance +ODS_VIRTUAL_NAME=api +ADMIN_API_VIRTUAL_NAME=adminapi +LOGS_FOLDER=/tmp/logs + +# For Authentication +ISSUER_URL=https://localhost/${ADMIN_API_VIRTUAL_NAME} +SIGNING_KEY=TDMyNH0lJmo7aDRnNXYoSmAwSXQpV09nbitHSWJTKn0= + +PAGING_OFFSET=0 +PAGING_LIMIT=25 + +# The following needs to be set to specify the ODS API endpoint for Admin API to internally connect. +# If user chooses direct connection between ODS API and Admin API within docker network, then set the api internal url as follows +API_INTERNAL_URL=http://${ODS_VIRTUAL_NAME} + +ADMIN_API_HEALTHCHECK_TEST="wget -nv -t1 --spider http://${ADMIN_API_VIRTUAL_NAME}/health || exit 1" + +# IdP db keycloak +KEYCLOAK_DB_IMAGE_TAG=16.2 +KEYCLOAK_POSTGRES_DB=keycloak_db +KEYCLOAK_POSTGRES_USER=edfi +KEYCLOAK_POSTGRES_PASSWORD=P@55w0rd +# IdP keycloak +KEYCLOAK_IMAGE_TAG=26.0 +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=admin +KEYCLOAK_PORT=28080 +KEYCLOAK_VIRTUAL_NAME=keycloak +KEYCLOAK_HOSTNAME= localhost +KEYCLOAK_HOSTNAME_PORT=443 +KEYCLOAK_HOSTNAME_STRICT_BACKCHANNEL=false +KEYCLOAK_HTTP_ENABLED=true +KEYCLOAK_HOSTNAME_STRICT_HTTPS=true +KEYCLOAK_HEALTH_ENABLED=true +KEYCLOAK_ADMIN_CONSOLE_REALM=myrealm + diff --git a/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_pgsql.env b/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_pgsql.env new file mode 100644 index 000000000..69774ada8 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi/E2E Tests/gh-action-setup/.automation_api_idp_pgsql.env @@ -0,0 +1,39 @@ +API_MODE=SharedInstance +ODS_VIRTUAL_NAME=api +ADMIN_API_VIRTUAL_NAME=adminapi +LOGS_FOLDER=/tmp/logs + +# For Authentication +ISSUER_URL=https://localhost/${ADMIN_API_VIRTUAL_NAME} +SIGNING_KEY=TDMyNH0lJmo7aDRnNXYoSmAwSXQpV09nbitHSWJTKn0= + +# For Postgres only +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +PGBOUNCER_LISTEN_PORT=6432 + +# The following needs to be set to specify the ODS API endpoint for Admin API to internally connect. +# If user chooses direct connection between ODS API and Admin API within docker network, then set the api internal url as follows +API_INTERNAL_URL=http://${ODS_VIRTUAL_NAME} + +ADMIN_API_HEALTHCHECK_TEST="wget -nv -t1 --spider http://${ADMIN_API_VIRTUAL_NAME}/health || exit 1" + +# IdP db keycloak +KEYCLOAK_DB_IMAGE_TAG=16.2 +KEYCLOAK_POSTGRES_DB=keycloak_db +KEYCLOAK_POSTGRES_USER=edfi +KEYCLOAK_POSTGRES_PASSWORD=P@55w0rd +# IdP keycloak +KEYCLOAK_IMAGE_TAG=26.0 +KEYCLOAK_ADMIN=admin +KEYCLOAK_ADMIN_PASSWORD=admin +KEYCLOAK_PORT=28080 +KEYCLOAK_VIRTUAL_NAME=keycloak +KEYCLOAK_HOSTNAME= localhost +KEYCLOAK_HOSTNAME_PORT=443 +KEYCLOAK_HOSTNAME_STRICT_BACKCHANNEL=false +KEYCLOAK_HTTP_ENABLED=true +KEYCLOAK_HOSTNAME_STRICT_HTTPS=true +KEYCLOAK_HEALTH_ENABLED=true +KEYCLOAK_ADMIN_CONSOLE_REALM=myrealm + diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml index 21a4a772e..1b71a53e3 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml @@ -7,7 +7,7 @@ services: nginx: build: context: ../../../Settings/gateway/ - dockerfile: Dockerfile + dockerfile: Dockerfile_IDP environment: ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" KEYCLOAK_VIRTUAL_NAME: ${KEYCLOAK_VIRTUAL_NAME:-auth} diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml index 32bc26c97..d4094709f 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-dev-multi-tenant.yml @@ -7,7 +7,7 @@ services: nginx: build: context: ../../../Settings/gateway/ - dockerfile: Dockerfile + dockerfile: Dockerfile_IDP environment: ADMIN_API_VIRTUAL_NAME: "${ADMIN_API_VIRTUAL_NAME:-adminapi}" ODS_VIRTUAL_NAME: "${ODS_VIRTUAL_NAME:-api}" diff --git a/docs/developer.md b/docs/developer.md index a45d806f3..3a38dc31d 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -2,30 +2,30 @@ ## Contents -- [Admin API Developer Instructions](#admin-api-developer-instructions) - - [Contents](#contents) - - [Development Pre-Requisites](#development-pre-requisites) - - [Build Script](#build-script) - - [Running on Localhost](#running-on-localhost) - - [Configuring Admin API to Run with the ODS/API](#configuring-admin-api-to-run-with-the-odsapi) - - [Resetting the Database State](#resetting-the-database-state) - - [Running Locally in Docker](#running-locally-in-docker) - - [Testing Admin API](#testing-admin-api) - - [Application Architecture](#application-architecture) - - [Database Layer](#database-layer) - - [Validation](#validation) +* [Admin API Developer Instructions](#admin-api-developer-instructions) + * [Contents](#contents) + * [Development Pre-Requisites](#development-pre-requisites) + * [Build Script](#build-script) + * [Running on Localhost](#running-on-localhost) + * [Configuring Admin API to Run with the ODS/API](#configuring-admin-api-to-run-with-the-odsapi) + * [Resetting the Database State](#resetting-the-database-state) + * [Running Locally in Docker](#running-locally-in-docker) + * [Testing Admin API](#testing-admin-api) + * [Application Architecture](#application-architecture) + * [Database Layer](#database-layer) + * [Validation](#validation) ## Development Pre-Requisites -- [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) -- Suggested to have either: - - [Visual Studio 2022](https://visualstudio.microsoft.com/downloads), or - - [Visual Studio 2022 Build +* [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) +* Suggested to have either: + * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads), or + * [Visual Studio 2022 Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) (install the ".NET Build Tools" component) -- Clone [this +* Clone [this repository](https://github.com/Ed-Fi-Alliance-OSS/Ed-Fi-ODS-AdminApi) locally -- To work with the official Ed-Fi Docker solution, also clone the [Docker +* To work with the official Ed-Fi Docker solution, also clone the [Docker repository](https://github.com/Ed-Fi-Alliance-OSS/Ed-Fi-ODS-Docker). ## Build Script @@ -37,23 +37,23 @@ as needed (nuget, nunit). Available command (e.g. `./build.ps1 clean`) (commands are not case sensitive): -- `clean`: runs `dotnet clean` -- `build`: runs `dotnet build` with several implicit steps +* `clean`: runs `dotnet clean` +* `build`: runs `dotnet build` with several implicit steps (clean, restore, inject version information). -- `unitTest`: executes NUnit tests in projects named `*.UnitTests`, which +* `unitTest`: executes NUnit tests in projects named `*.UnitTests`, which do not connect to a database. -- `integrationTest`: executes NUnit tests in projects named `*.Test`, +* `integrationTest`: executes NUnit tests in projects named `*.Test`, which connect to a database. Includes drop and deploy operations for installing fresh test databases compatible with Ed-Fi ODS/API 3.4 and 5.3. -- `buildAndTest`: executes the Build, UnitTest, and IntegrationTest +* `buildAndTest`: executes the Build, UnitTest, and IntegrationTest commands. -- `package`: builds pre-release and release NuGet packages for the Admin +* `package`: builds pre-release and release NuGet packages for the Admin App web application. -- `push`: uploads a NuGet package to the NuGet feed. -- `buildAndDeployToAdminApiDockerContainer`: runs the build operation, update +* `push`: uploads a NuGet package to the NuGet feed. +* `buildAndDeployToAdminApiDockerContainer`: runs the build operation, update the `appsettings.json` with provided Docker environment variables and copy over the latest files to existing AdminApi docker container for testing. -- `run`: runs the Admin API +* `run`: runs the Admin API Note: use the `IsLocalBuild` switch to install NuGet.exe if you do not already have it in your local path. @@ -65,10 +65,10 @@ arguments. There are three ways of running Admin API: -- `build.ps1 run` to run from the command line. -- Run inside a container with the help of +* `build.ps1 run` to run from the command line. +* Run inside a container with the help of [compose-build-dev.yml](../Docker/Compose/pgsql/compose-build-dev.yml). -- Start from Visual Studio to take advantage of easy debugging integration. +* Start from Visual Studio to take advantage of easy debugging integration. There are several launch profiles available either with `build.ps1` or when running from Visual Studio. Review @@ -89,9 +89,9 @@ Docker network from Admin API, because at present both need to access the same `EdFi_Admin` and `EdFi_Security` databases. If starting up manually, make sure that both Admin API and ODS/API have the same deployment setting: -- `sharedinstance` -- `yearspecific` -- `districtspecific` +* `sharedinstance` +* `yearspecific` +* `districtspecific` In Admin API, you set this value in the `appsettings.json` file under `AppSettings.ApiStartupType`. In the ODS/API, you set it as the @@ -157,12 +157,32 @@ eng/run-dbup-migrations.ps1 As mentioned above, you can run locally in Docker. See [docker.md](docker.md) for more information. +### Using Keycloak (IDP) + +To use Keycloak for authenticating the API, you need to configure the parameters in the OIDC section. Additionally, you must specify with `"UseSelfcontainedAuthorization": false`, that the API’s own authentication will be disabled in favor of using Keycloak. + +Furthermore, when using Keycloak, the Register and Token endpoints will not be available in Swagger or for direct calls. Attempting to access these endpoints will result in a 404 error. + +``` +"Authentication": { + "IssuerUrl": "", + "SigningKey": "", + "AllowRegistration": false, + "OIDC": { + "Authority": "https://localhost/auth/realms/myrealm", + "ValidateIssuer": true, + "RequireHttpsMetadata": false, + "EnableServerCertificateCustomValidationCallback": true + } + }, +``` + ## Testing Admin API In source code there are two test projects: -- Unit tests that are completely isolated. -- The DB Tests project is a set of _integration_ tests that exercise the +* Unit tests that are completely isolated. +* The DB Tests project is a set of _integration_ tests that exercise the repository layer. Additionally there is a set of end-to-end (E2E) tests in Postman. See the [E2E diff --git a/docs/docker.md b/docs/docker.md index 6a35f44fb..9d3cc5c39 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -86,7 +86,7 @@ style I fill:#fff ``` > [!NOTE] - > The .env file is a shared resource that can be referenced by both the + > The .env file is a shared resource that can be referenced by both the > "MultiTenant" and "SingleTenant" compose files. 3. Build local containers (optional step; next step will run the build implicitly) @@ -171,7 +171,7 @@ style D fill:#fff ``` Instructions are similar to the localhost quickstart above, except use -`compose-build-binaries.yml` instead of `compose-build-dev.yml`. +`compose-build-binaries.yml`, `compose-build-idp-binaries.yml` or `compose-build-idp-dev.yml` instead of `compose-build-dev.yml`. ## Multi-Tenant @@ -180,9 +180,11 @@ Instructions are similar to the Local Development and Pre-Built Binaries setups Tenants details can be configured on appsettings.dockertemplate.json file. For local development and testing, use `MultiTenant/compose-build-dev-multi-tenant.yml`. +For local development and testing with keycloak, use `MultiTenant/compose-build-idp-dev-multi-tenant.yml`. For testing pre-built binaries, use `MultiTenant/compose-build-binaries-multi-tenant.yml`. +For testing pre-built binaries with keycloak, use `MultiTenant/compose-build-idp-binaries-multi-tenant.yml`. ## Admin Api and Ed-Fi ODS / API docker containers -Please refer [DOCKER DEPLOYMENT](https://techdocs.ed-fi.org/display/EDFITOOLS/Docker+Deployment) for +Please refer [DOCKER DEPLOYMENT](https://techdocs.ed-fi.org/display/EDFITOOLS/Docker+Deployment) for installing and configuring Admin Api along with Ed-Fi ODS / API on Docker containers for testing. From 3576e87ec13b5e87f77bcf8838cc7e9b14b09c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Wed, 12 Feb 2025 08:41:49 -0600 Subject: [PATCH 4/6] Update docker compose parameters Update parameters to include values to use an IDP --- Docker/Compose/mssql/.env-idp.example | 2 ++ .../MultiTenant/compose-build-binaries-multi-tenant.yml | 8 ++++---- .../pgsql/MultiTenant/compose-build-dev-multi-tenant.yml | 8 ++++---- .../compose-build-idp-binaries-multi-tenant.yml | 2 +- .../Compose/pgsql/SingleTenant/compose-build-binaries.yml | 8 ++++---- Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml | 8 ++++---- .../pgsql/SingleTenant/compose-build-idp-binaries.yml | 2 +- .../Compose/pgsql/SingleTenant/compose-build-idp-dev.yml | 2 +- 8 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Docker/Compose/mssql/.env-idp.example b/Docker/Compose/mssql/.env-idp.example index 728a37b11..1ee0fbaa4 100644 --- a/Docker/Compose/mssql/.env-idp.example +++ b/Docker/Compose/mssql/.env-idp.example @@ -20,9 +20,11 @@ SIGNING_KEY= ENABLE_ADMIN_CONSOLE=true USE_SELF_CONTAINED_AUTH=false +OIDC_AUTHORITY=http://ed-fi-keycloak:8080/auth/realms/myrealm OIDC_REQUIRE_METADATA=false OIDC_ENABLE_SERVER_CERTIFICATE=true + PAGING_OFFSET=0 PAGING_LIMIT=25 # For MSSQL only diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml index 99b8651aa..210b3e279 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-binaries-multi-tenant.yml @@ -42,10 +42,10 @@ services: AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ASPNETCORE_ENVIRONMENT: "multitenantdocker" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} - USE_SELF_CONTAINED_AUTH: true - OIDC_AUTHORITY: "" - OIDC_REQUIRE_METADATA: "" - OIDC_ENABLE_SERVER_CERTIFICATE: "" + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml index 79bd19c24..accfb1b95 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-dev-multi-tenant.yml @@ -47,10 +47,10 @@ services: AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ASPNETCORE_ENVIRONMENT: "multitenantdocker" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} - USE_SELF_CONTAINED_AUTH: true - OIDC_AUTHORITY: "" - OIDC_REQUIRE_METADATA: "" - OIDC_ENABLE_SERVER_CERTIFICATE: "" + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" volumes: - ./appsettings.dockertemplate.json:/app/appsettings.dockertemplate.json entrypoint: ["/bin/sh"] diff --git a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml index 1b71a53e3..d980debfb 100644 --- a/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml +++ b/Docker/Compose/pgsql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml @@ -45,7 +45,7 @@ services: ASPNETCORE_ENVIRONMENT: "multitenantdocker" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} - OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" volumes: diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml index 77cf754b4..62127ecd8 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-binaries.yml @@ -42,10 +42,10 @@ services: AppSettings__DefaultPageSizeLimit: ${PAGING_LIMIT:-25} AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} - USE_SELF_CONTAINED_AUTH: true - OIDC_AUTHORITY: "" - OIDC_REQUIRE_METADATA: "" - OIDC_ENABLE_SERVER_CERTIFICATE: "" + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" depends_on: - db-admin restart: always diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml index 72bf732a2..8f4d291df 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-dev.yml @@ -43,10 +43,10 @@ services: ADMIN_API_VIRTUAL_NAME: ${ADMIN_API_VIRTUAL_NAME:-adminapi} MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} - USE_SELF_CONTAINED_AUTH: true - OIDC_AUTHORITY: "" - OIDC_REQUIRE_METADATA: "" - OIDC_ENABLE_SERVER_CERTIFICATE: "" + USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" + OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" + OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" depends_on: - pb-admin restart: always diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml index 1b1908d05..63bcd1524 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-binaries.yml @@ -45,7 +45,7 @@ services: AppSettings__PreventDuplicateApplications: "${PREVENT_DUPLICATE_APPLICATIONS:-false}" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} - OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" depends_on: diff --git a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml index 60deb8bd2..6c792d043 100644 --- a/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml +++ b/Docker/Compose/pgsql/SingleTenant/compose-build-idp-dev.yml @@ -46,7 +46,7 @@ services: MULTITENANCY_ENABLED: "${MULTITENANCY_ENABLED:-false}" ENABLE_ADMIN_CONSOLE: ${ENABLE_ADMIN_CONSOLE:-true} USE_SELF_CONTAINED_AUTH: ${USE_SELF_CONTAINED_AUTH:-true} - OIDC_AUTHORITY: "http://ed-fi-keycloak:8080/auth/realms/myrealm" + OIDC_AUTHORITY: "${OIDC_AUTHORITY:-http://ed-fi-keycloak:8080/auth/realms/myrealm}" OIDC_REQUIRE_METADATA: "${OIDC_REQUIRE_METADATA:-false}" OIDC_ENABLE_SERVER_CERTIFICATE: "${OIDC_ENABLE_SERVER_CERTIFICATE:-true}" depends_on: From 5e45165c4a89edfa99fbeff8ae6f507ea4f205df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Wed, 12 Feb 2025 14:44:11 -0600 Subject: [PATCH 5/6] Remove usings --- .../WebApplicationBuilderExtensions.cs | 18 ++++++++---------- ...compose-build-idp-binaries-multi-tenant.yml | 2 +- .../compose-build-idp-binaries.yml | 2 +- Docker/Settings/gateway/Dockerfile_IDP | 12 ++++++++---- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs index 37a692531..ae6820dd1 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/WebApplicationBuilderExtensions.cs @@ -5,24 +5,22 @@ using System.Reflection; using EdFi.Admin.DataAccess.Contexts; -using EdFi.Ods.AdminApi.Infrastructure.Documentation; -using EdFi.Ods.AdminApi.Infrastructure.Security; +using EdFi.Common.Extensions; +using EdFi.Ods.AdminApi.Helpers; using EdFi.Ods.AdminApi.Infrastructure.Api; +using EdFi.Ods.AdminApi.Infrastructure.Context; +using EdFi.Ods.AdminApi.Infrastructure.Documentation; using EdFi.Ods.AdminApi.Infrastructure.Extensions; -using EdFi.Security.DataAccess.Contexts; +using EdFi.Ods.AdminApi.Infrastructure.MultiTenancy; +using EdFi.Ods.AdminApi.Infrastructure.Security; using EdFi.Ods.AdminApi.Infrastructure.Services; +using EdFi.Security.DataAccess.Contexts; +using FluentValidation; using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Http.Json; using Microsoft.EntityFrameworkCore; using Microsoft.Net.Http.Headers; using Microsoft.OpenApi.Models; -using FluentValidation; -using EdFi.Ods.AdminApi.Infrastructure.MultiTenancy; -using EdFi.Ods.AdminApi.Helpers; -using EdFi.Ods.AdminApi.Infrastructure.Context; -using EdFi.Common.Extensions; -using System.Configuration; -using Microsoft.AspNetCore.Mvc.Filters; namespace EdFi.Ods.AdminApi.Infrastructure; diff --git a/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml b/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml index d2eb4b027..4d9293b39 100644 --- a/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml +++ b/Docker/Compose/mssql/MultiTenant/compose-build-idp-binaries-multi-tenant.yml @@ -19,7 +19,7 @@ services: hostname: nginx volumes: - ../../../Settings/ssl:/ssl/ - - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + - ../../../Settings/gateway/default_idp.conf.template:/etc/nginx/templates/default.conf.template depends_on: - adminapi - idp-keycloak diff --git a/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml b/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml index 2d4788109..553302fa2 100644 --- a/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml +++ b/Docker/Compose/mssql/SingleTenant/compose-build-idp-binaries.yml @@ -19,7 +19,7 @@ services: hostname: nginx volumes: - ../../../Settings/ssl:/ssl/ - - ../../../Settings/gateway/default.conf.template:/etc/nginx/templates/default.conf.template + - ../../../Settings/gateway/default_idp.conf.template:/etc/nginx/templates/default.conf.template depends_on: - adminapi - idp-keycloak diff --git a/Docker/Settings/gateway/Dockerfile_IDP b/Docker/Settings/gateway/Dockerfile_IDP index 597606f53..a924a54f1 100644 --- a/Docker/Settings/gateway/Dockerfile_IDP +++ b/Docker/Settings/gateway/Dockerfile_IDP @@ -1,12 +1,16 @@ # SPDX-License-Identifier: Apache-2.0 -# Licensed to the Ed-Fi Alliance under one or more agreements. -# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. -# See the LICENSE and NOTICES files in the project root for more information. + +# Licensed to the Ed-Fi Alliance under one or more agreements + +# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0 + +# See the LICENSE and NOTICES files in the project root for more information # Tag nginx:alpine3.20 + FROM nginx@sha256:2140dad235c130ac861018a4e13a6bc8aea3a35f3a40e20c1b060d51a7efd250 LABEL maintainer="Ed-Fi Alliance, LLC and Contributors " -COPY ./default_idp.conf.template /etc/nginx/templates/ +COPY ./default_idp.conf.template /etc/nginx/templates/default.conf.template EXPOSE 443 From 745446fb65bab7e3c7b1b9ec79308ebb3b73c5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Leiva=20Obando?= Date: Wed, 12 Feb 2025 16:18:39 -0600 Subject: [PATCH 6/6] Replace env-idp.example --- Docker/Compose/mssql/{.env-idp.example => env-idp.example} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Docker/Compose/mssql/{.env-idp.example => env-idp.example} (100%) diff --git a/Docker/Compose/mssql/.env-idp.example b/Docker/Compose/mssql/env-idp.example similarity index 100% rename from Docker/Compose/mssql/.env-idp.example rename to Docker/Compose/mssql/env-idp.example