From 8be71b91f117858ee577302e2804675468160f9f Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Mon, 3 Oct 2022 19:15:56 +0300 Subject: [PATCH 01/32] added keycloak image to docker compose --- .../docker-compose.infrastructure.override.yml | 14 +++++++++++++- etc/docker/docker-compose.infrastructure.yml | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/etc/docker/docker-compose.infrastructure.override.yml b/etc/docker/docker-compose.infrastructure.override.yml index 3ae3deb5..22018264 100644 --- a/etc/docker/docker-compose.infrastructure.override.yml +++ b/etc/docker/docker-compose.infrastructure.override.yml @@ -1,4 +1,4 @@ -version: '3.7' +version: '3.8' services: rabbitmq: @@ -18,6 +18,7 @@ services: ports: - "5432:5432" environment: + POSTGRES_DB: keycloak POSTGRES_PASSWORD: "myPassw0rd" pgadmin: @@ -26,3 +27,14 @@ services: environment: PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org} PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin} + + keycloak: + ports: + - "44320:8080" + environment: + DB_VENDOR: postgres + DB_ADDR: "postgres-db" + DB_DATABASE: "keycloak" + DB_USER: "postgres" + DB_PASSWORD: "myPassw0rd" + \ No newline at end of file diff --git a/etc/docker/docker-compose.infrastructure.yml b/etc/docker/docker-compose.infrastructure.yml index 547b3aae..800073f8 100644 --- a/etc/docker/docker-compose.infrastructure.yml +++ b/etc/docker/docker-compose.infrastructure.yml @@ -1,4 +1,4 @@ -version: '3.7' +version: '3.8' services: rabbitmq: @@ -46,12 +46,21 @@ services: - eshoponabp-network pgadmin: - container_name: pgadmin_container + container_name: pgadmin image: dpage/pgadmin4:6.2 volumes: - pgadmin_data:/var/lib/pgadmin networks: - - eshoponabp-network + - eshoponabp-network + + keycloak: + container_name: keycloak + image: jboss/keycloak:13.0.0 + depends_on: + - postgres-db + restart: unless-stopped + networks: + - eshoponabp-network volumes: postgres_data: From b2954cfaae1307a87d8c5148049aaf3857134c96 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 5 Oct 2022 15:38:42 +0300 Subject: [PATCH 02/32] keycloak docker image update --- etc/docker/docker-compose.infrastructure.override.yml | 5 +++++ etc/docker/docker-compose.infrastructure.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/etc/docker/docker-compose.infrastructure.override.yml b/etc/docker/docker-compose.infrastructure.override.yml index 22018264..249946e7 100644 --- a/etc/docker/docker-compose.infrastructure.override.yml +++ b/etc/docker/docker-compose.infrastructure.override.yml @@ -37,4 +37,9 @@ services: DB_DATABASE: "keycloak" DB_USER: "postgres" DB_PASSWORD: "myPassw0rd" + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + KC_HEALTH_ENABLED: true + entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev"] + \ No newline at end of file diff --git a/etc/docker/docker-compose.infrastructure.yml b/etc/docker/docker-compose.infrastructure.yml index 800073f8..3f72762f 100644 --- a/etc/docker/docker-compose.infrastructure.yml +++ b/etc/docker/docker-compose.infrastructure.yml @@ -55,7 +55,7 @@ services: keycloak: container_name: keycloak - image: jboss/keycloak:13.0.0 + image: quay.io/keycloak/keycloak:19.0.2 depends_on: - postgres-db restart: unless-stopped From fdd9e23221c44df132785c4434856cba50b4ba8d Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 6 Oct 2022 10:06:32 +0300 Subject: [PATCH 03/32] added configuration --- .../EShopOnAbpPublicWebModule.cs | 79 ++++++++++++++----- .../src/EShopOnAbp.PublicWeb/appsettings.json | 8 ++ ...docker-compose.infrastructure.override.yml | 4 +- .../appsettings.json | 4 +- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index 58e1f408..0bc83acb 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -141,27 +141,68 @@ public class EShopOnAbpPublicWebModule : AbpModule .AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromDays(365); }) .AddAbpOpenIdConnect("oidc", options => { - options.Authority = configuration["AuthServer:Authority"]; - options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); - options.ResponseType = OpenIdConnectResponseType.CodeIdToken; - - options.ClientId = configuration["AuthServer:ClientId"]; - options.ClientSecret = configuration["AuthServer:ClientSecret"]; - - options.SaveTokens = true; + /* + * ASP.NET core uses the http://*:5000 and https://*:5001 ports for default communication with the OIDC middleware + * The app requires load balancing services to work with :80 or :443 + * These needs to be added to the keycloak client, in order for the redirect to work. + * If you however intend to use the app by itself then, + * Change the ports in launchsettings.json, but beware to also change the options.CallbackPath and options.SignedOutCallbackPath! + * Use LB services whenever possible, to reduce the config hazzle :) + */ + + //Use default signin scheme + // options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + //Keycloak server + options.Authority = configuration["Keycloak:ServerRealm"]; + //Keycloak client ID + options.ClientId = configuration["Keycloak:ClientId"]; + //Keycloak client secret + options.ClientSecret = configuration["Keycloak:ClientSecret"]; + //Keycloak .wellknown config origin to fetch config + options.MetadataAddress = configuration["Keycloak:Metadata"]; + //Require keycloak to use SSL + options.RequireHttpsMetadata = false; options.GetClaimsFromUserInfoEndpoint = true; - - options.Scope.Add("role"); - options.Scope.Add("email"); - options.Scope.Add("phone"); - options.Scope.Add("AccountService"); - options.Scope.Add("AdministrationService"); - options.Scope.Add("BasketService"); - options.Scope.Add("CatalogService"); - options.Scope.Add("PaymentService"); - options.Scope.Add("OrderingService"); - options.Scope.Add("CmskitService"); + options.Scope.Add("openid"); + options.Scope.Add("profile"); + //Save the token + options.SaveTokens = true; + //Token response type, will sometimes need to be changed to IdToken, depending on config. + options.ResponseType = OpenIdConnectResponseType.Code; + //SameSite is needed for Chrome/Firefox, as they will give http error 500 back, if not set to unspecified. + // options.NonceCookie.SameSite = SameSiteMode.Unspecified; + // options.CorrelationCookie.SameSite = SameSiteMode.Unspecified; + // + // options.TokenValidationParameters = new TokenValidationParameters + // { + // NameClaimType = "name", + // RoleClaimType = ClaimTypes.Role, + // ValidateIssuer = true + // }; }); + // .AddAbpOpenIdConnect("oidc", options => + // { + // options.Authority = configuration["AuthServer:Authority"]; + // options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); + // options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + // + // options.ClientId = configuration["AuthServer:ClientId"]; + // options.ClientSecret = configuration["AuthServer:ClientSecret"]; + // + // options.SaveTokens = true; + // options.GetClaimsFromUserInfoEndpoint = true; + // + // options.Scope.Add("role"); + // options.Scope.Add("email"); + // options.Scope.Add("phone"); + // options.Scope.Add("AccountService"); + // options.Scope.Add("AdministrationService"); + // options.Scope.Add("BasketService"); + // options.Scope.Add("CatalogService"); + // options.Scope.Add("PaymentService"); + // options.Scope.Add("OrderingService"); + // options.Scope.Add("CmskitService"); + // }); if (Convert.ToBoolean(configuration["AuthServer:IsOnProd"])) { context.Services.Configure("oidc", options => diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json index 8d0d9e5b..bcf0d7ef 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json @@ -43,6 +43,14 @@ "IsOnProd": "false", "MetaAddress": "https://localhost:44330" }, + "Keycloak": { + "ServerRealm": "http://localhost:8080/realms/master", + "Metadata": "http://localhost:8080/realms/master/.well-known/openid-configuration", + "ClientId": "PublicWeb", + "ClientSecret": "mPpj650ADqHwQ0g9qvwWNxCqQmefrGw7", + "TokenExchange": "http://localhost:8080/realms/master/protocol/openid-connect/token", + "Audience": "some-audience" + }, "ReverseProxy": { "Routes": { "route1" : { diff --git a/etc/docker/docker-compose.infrastructure.override.yml b/etc/docker/docker-compose.infrastructure.override.yml index 249946e7..c3c7ddeb 100644 --- a/etc/docker/docker-compose.infrastructure.override.yml +++ b/etc/docker/docker-compose.infrastructure.override.yml @@ -30,7 +30,7 @@ services: keycloak: ports: - - "44320:8080" + - "8080:8080" environment: DB_VENDOR: postgres DB_ADDR: "postgres-db" @@ -41,5 +41,5 @@ services: KEYCLOAK_ADMIN_PASSWORD: admin KC_HEALTH_ENABLED: true entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev"] - + \ No newline at end of file diff --git a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json index 8610b450..620ba213 100644 --- a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json +++ b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, From be6dbd4c9e611eaf576d05e30c4cae47c1566e96 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 6 Oct 2022 21:49:41 +0300 Subject: [PATCH 04/32] updated openid configurations --- .../EShopOnAbpPublicWebModule.cs | 15 ++++++++++++++- .../src/EShopOnAbp.PublicWeb/appsettings.json | 1 - 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index 0bc83acb..a0aec3a1 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -23,6 +23,7 @@ using Polly; using StackExchange.Redis; using System; using System.Net.Http.Headers; +using Microsoft.AspNetCore.Authentication.OAuth.Claims; using Volo.Abp; using Volo.Abp.Account; using Volo.Abp.AspNetCore.Authentication.OpenIdConnect; @@ -42,6 +43,7 @@ using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.IdentityModel.Web; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; +using Volo.Abp.Security.Claims; using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation.Urls; using Volo.Abp.VirtualFileSystem; @@ -157,7 +159,7 @@ public class EShopOnAbpPublicWebModule : AbpModule //Keycloak client ID options.ClientId = configuration["Keycloak:ClientId"]; //Keycloak client secret - options.ClientSecret = configuration["Keycloak:ClientSecret"]; + // options.ClientSecret = configuration["Keycloak:ClientSecret"]; //Keycloak .wellknown config origin to fetch config options.MetadataAddress = configuration["Keycloak:Metadata"]; //Require keycloak to use SSL @@ -165,6 +167,10 @@ public class EShopOnAbpPublicWebModule : AbpModule options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("openid"); options.Scope.Add("profile"); + options.Scope.Add("email"); + options.Scope.Add("phone"); + options.Scope.Add("roles"); + options.Scope.Add("offline_access"); //Save the token options.SaveTokens = true; //Token response type, will sometimes need to be changed to IdToken, depending on config. @@ -179,6 +185,13 @@ public class EShopOnAbpPublicWebModule : AbpModule // RoleClaimType = ClaimTypes.Role, // ValidateIssuer = true // }; + + if (AbpClaimTypes.UserName != "preferred_username") + { + options.ClaimActions.MapJsonKey(AbpClaimTypes.UserName, "preferred_username"); + options.ClaimActions.DeleteClaim("preferred_username"); + options.ClaimActions.RemoveDuplicate(AbpClaimTypes.UserName); + } }); // .AddAbpOpenIdConnect("oidc", options => // { diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json index bcf0d7ef..e82d3b47 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json @@ -47,7 +47,6 @@ "ServerRealm": "http://localhost:8080/realms/master", "Metadata": "http://localhost:8080/realms/master/.well-known/openid-configuration", "ClientId": "PublicWeb", - "ClientSecret": "mPpj650ADqHwQ0g9qvwWNxCqQmefrGw7", "TokenExchange": "http://localhost:8080/realms/master/protocol/openid-connect/token", "Audience": "some-audience" }, From 0306146bad35e55ec8aa2f448603ced341df0f10 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 7 Oct 2022 16:22:14 +0300 Subject: [PATCH 05/32] Added keycloak migration service --- EShopOnAbp.sln | 7 ++ ...docker-compose.infrastructure.override.yml | 4 +- .../DbMigratorHostedService.cs | 48 ++++++++++ .../EShopOnAbp.Keycloak.DbMigrator.csproj | 34 +++++++ .../EShopOnAbpDbMigratorModule.cs | 21 +++++ .../KeyCloakDataSeeder.cs | 21 +++++ .../Keycloak/KeycloakClientOptions.cs | 6 ++ .../Keycloak/KeycloakService.cs | 94 +++++++++++++++++++ .../Keycloak/Models/AccessTokenResult.cs | 16 ++++ .../MigrationService.cs | 30 ++++++ .../EShopOnAbp.Keycloak.DbMigrator/Program.cs | 35 +++++++ .../appsettings.json | 3 + 12 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/MigrationService.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Program.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json diff --git a/EShopOnAbp.sln b/EShopOnAbp.sln index e7a4264d..73d5919b 100644 --- a/EShopOnAbp.sln +++ b/EShopOnAbp.sln @@ -43,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EShopOnAbp.BasketService", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EShopOnAbp.CmskitService.HttpApi.Host", "services\cmskit\src\EShopOnAbp.CmskitService.HttpApi.Host\EShopOnAbp.CmskitService.HttpApi.Host.csproj", "{D5B9D5A5-44AA-42F8-867C-95B54780C9DC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EShopOnAbp.Keycloak.DbMigrator", "shared\EShopOnAbp.Keycloak.DbMigrator\EShopOnAbp.Keycloak.DbMigrator.csproj", "{774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -113,6 +115,10 @@ Global {D5B9D5A5-44AA-42F8-867C-95B54780C9DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {D5B9D5A5-44AA-42F8-867C-95B54780C9DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {D5B9D5A5-44AA-42F8-867C-95B54780C9DC}.Release|Any CPU.Build.0 = Release|Any CPU + {774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -134,6 +140,7 @@ Global {7AE4C613-780E-4DA5-9B57-76F0D40D5146} = {F415FFFD-E52D-4EBE-98DC-067C1EFFFFE3} {E373DD66-3247-4D95-B325-064BBBC337B1} = {F415FFFD-E52D-4EBE-98DC-067C1EFFFFE3} {D5B9D5A5-44AA-42F8-867C-95B54780C9DC} = {F415FFFD-E52D-4EBE-98DC-067C1EFFFFE3} + {774C6ADF-BDD0-431C-A9F3-8BAFD5A49C8C} = {B8B59303-2178-459B-91A8-DF353044E090} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {26F82565-C6A4-439D-93A4-3251E3E7D5B0} diff --git a/etc/docker/docker-compose.infrastructure.override.yml b/etc/docker/docker-compose.infrastructure.override.yml index c3c7ddeb..7b9c83a2 100644 --- a/etc/docker/docker-compose.infrastructure.override.yml +++ b/etc/docker/docker-compose.infrastructure.override.yml @@ -38,8 +38,8 @@ services: DB_USER: "postgres" DB_PASSWORD: "myPassw0rd" KEYCLOAK_ADMIN: admin - KEYCLOAK_ADMIN_PASSWORD: admin - KC_HEALTH_ENABLED: true + KEYCLOAK_ADMIN_PASSWORD: "1q2w3E*" + KC_HEALTH_ENABLED: "true" entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev"] \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs new file mode 100644 index 00000000..ce020de4 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs @@ -0,0 +1,48 @@ +using System.Threading; +using System.Threading.Tasks; +using EShopOnAbp.DbMigrator.Keycloak; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Volo.Abp; + +namespace EShopOnAbp.DbMigrator; + +public class DbMigratorHostedService : IHostedService +{ + private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IConfiguration _configuration; + + public DbMigratorHostedService( + IHostApplicationLifetime hostApplicationLifetime, + IConfiguration configuration) + { + _hostApplicationLifetime = hostApplicationLifetime; + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + })) + { + application.Initialize(); + + await application + .ServiceProvider + .GetRequiredService() + .MigrateAsync(cancellationToken); + + application.Shutdown(); + + _hostApplicationLifetime.StopApplication(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj new file mode 100644 index 00000000..98834c63 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj @@ -0,0 +1,34 @@ + + + + Exe + net6.0 + EShopOnAbp.DbMigrator + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + Always + + + + diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs new file mode 100644 index 00000000..f739f1e6 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs @@ -0,0 +1,21 @@ +using EShopOnAbp.DbMigrator.Keycloak; +using EShopOnAbp.Shared.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace EShopOnAbp.DbMigrator; + +[DependsOn( + typeof(EShopOnAbpSharedHostingModule) +)] +public class EShopOnAbpDbMigratorModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + context.Services.AddHttpClient(KeycloakService.HttpClientName); + + Configure(configuration); + } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs new file mode 100644 index 00000000..abd7dcfa --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using EShopOnAbp.DbMigrator.Keycloak; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace EShopOnAbp.DbMigrator; + +public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency +{ + private readonly KeycloakService _keycloakService; + + public KeyCloakDataSeeder(KeycloakService keycloakService) + { + _keycloakService = keycloakService; + } + + public async Task SeedAsync(DataSeedContext context) + { + var result = await _keycloakService.GetAdminAccessTokenAsync("master"); + } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs new file mode 100644 index 00000000..417638d7 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs @@ -0,0 +1,6 @@ +namespace EShopOnAbp.DbMigrator.Keycloak; + +public class KeycloakClientOptions +{ + +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs new file mode 100644 index 00000000..7a8c9a70 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using EShopOnAbp.DbMigrator.Keycloak.Models; +using Microsoft.Extensions.Logging; +using Volo.Abp.DependencyInjection; + +namespace EShopOnAbp.DbMigrator.Keycloak; + +public class KeycloakService : ITransientDependency +{ + public const string HttpClientName = "KeycloakServiceHttpClientName"; + + // TODO: Option + public const string BaseUrl = "http://localhost:8080/admin/realms"; + public const string AdminClientId = "admin-cli"; + public const string AdminUserName = "admin"; + public const string AdminPassword = "1q2w3E*"; + + private readonly ILogger _logger; + private readonly IHttpClientFactory _clientFactory; + + public KeycloakService(IHttpClientFactory clientFactory, ILogger logger) + { + _clientFactory = clientFactory; + _logger = logger; + } + + // public async Task CreateClientAsync(string realm, Client client) + // { + // HttpResponseMessage response = await InternalCreateClientAsync(realm, client).ConfigureAwait(false); + // + // var locationPathAndQuery = response.Headers.Location.PathAndQuery; + // var clientId = response.IsSuccessStatusCode + // ? locationPathAndQuery.Substring(locationPathAndQuery.LastIndexOf("/", StringComparison.Ordinal) + 1) + // : null; + // return clientId; + // } + + private HttpClient CreateKeycloakApiHttpClient(string realm) + { + var httpClient = _clientFactory.CreateClient(HttpClientName); + httpClient.BaseAddress = new Uri(BaseUrl); + + return httpClient; + } + + private async Task CreateKeycloakApiHttpClientAsync(string realm, string token = null) + { + var httpClient = CreateKeycloakApiHttpClient(realm); + httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + if (!string.IsNullOrEmpty(token)) + { + var accessToken = await GetAdminAccessTokenAsync(realm); + httpClient.DefaultRequestHeaders.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue($"Bearer", $"{accessToken}"); + } + + return httpClient; + } + + public async Task GetAdminAccessTokenAsync(string realm) + { + var httpClient = _clientFactory.CreateClient(HttpClientName); + httpClient.BaseAddress = new Uri(BaseUrl); + + var result = string.Empty; + + var formContent = new FormUrlEncodedContent(new[] + { + new KeyValuePair("client_id", AdminClientId), + new KeyValuePair("username", AdminUserName), + new KeyValuePair("password", AdminPassword), + new KeyValuePair("grant_type", "password") + }); + + var httpResponseMessage = + await httpClient.PostAsync($"/realms/{realm}/protocol/openid-connect/token", formContent); + + if (httpResponseMessage.IsSuccessStatusCode) + { + var response = await httpResponseMessage.Content.ReadFromJsonAsync(); + result = response?.AccessToken; + } + + return result; + } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs new file mode 100644 index 00000000..83d2266b --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace EShopOnAbp.DbMigrator.Keycloak.Models; + +public class AccessTokenResult +{ + [JsonPropertyName("access_token")] public string AccessToken { get; set; } + [JsonPropertyName("expires_in")] public int Expiration { get; set; } + [JsonPropertyName("refresh_token")] public string RefreshToken { get; set; } + + [JsonPropertyName("refresh_expires_in")] + public int RefreshExpiration { get; set; } + + [JsonPropertyName("token_type")] public string TokenType { get; set; } + [JsonPropertyName("scope")] public string Scope { get; set; } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/MigrationService.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/MigrationService.cs new file mode 100644 index 00000000..aa0cf304 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/MigrationService.cs @@ -0,0 +1,30 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace EShopOnAbp.DbMigrator; + +public class MigrationService: ITransientDependency +{ + private readonly ILogger _logger; + private readonly IDataSeeder _dataSeeder; + + public MigrationService(ILogger logger, IDataSeeder dataSeeder) + { + _logger = logger; + _dataSeeder = dataSeeder; + } + + public async Task MigrateAsync(CancellationToken cancellationToken) + { + // Check if keycloak api is available + + //Seed data + await _dataSeeder.SeedAsync(); + + _logger.LogInformation("Migration completed!"); + } + +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Program.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Program.cs new file mode 100644 index 00000000..bd60e4fa --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/Program.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using EShopOnAbp.DbMigrator; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; + +class Program +{ + async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() +#if DEBUG + .MinimumLevel.Debug() +#else + .MinimumLevel.Information() +#endif + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .Enrich.FromLogContext() + .Enrich.WithProperty("Application", $"DbMigrator") + .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.Console()) + .CreateLogger(); + + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureLogging((context, logging) => logging.ClearProviders()) + .ConfigureServices((hostContext, services) => { services.AddHostedService(); }); +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json new file mode 100644 index 00000000..077404aa --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file From 2a227f2100364f12364b93ffd43daa097ee03a24 Mon Sep 17 00:00:00 2001 From: selmankoc Date: Thu, 13 Oct 2022 07:17:31 +0300 Subject: [PATCH 06/32] update container registry --- etc/k8s/eshoponabp/values.azure.yaml | 45 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/etc/k8s/eshoponabp/values.azure.yaml b/etc/k8s/eshoponabp/values.azure.yaml index f57d5fb9..695e4dd2 100644 --- a/etc/k8s/eshoponabp/values.azure.yaml +++ b/etc/k8s/eshoponabp/values.azure.yaml @@ -18,8 +18,8 @@ authserver: host: auth.eshoponabp.com tlsSecret: eshop-wildcard-tls image: - repository: "volocr.azurecr.io/eshoponabp/app-authserver" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/app-authserver" + tag: 1.0.0 # web sub-chart override web: @@ -35,8 +35,8 @@ web: ingress: host: admin.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/app-web" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/app-web" + tag: 1.0.0 # public-web sub-chart override public-web: @@ -56,8 +56,8 @@ public-web: ingress: host: eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/app-publicweb" - tag: 1.0.6 + repository: "ghcr.io/volosoft/eshoponabp/app-publicweb" + tag: 1.0.0 # identity-service sub-chart override identity: @@ -91,8 +91,8 @@ identity: ingress: host: identity.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-identity" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/service-identity" + tag: 1.0.0 # administration sub-chart override administration: @@ -118,8 +118,8 @@ administration: ingress: host: administration.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-administration" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/service-administration" + tag: 1.0.0 # gateway-web sub-chart override gateway-web: @@ -139,8 +139,8 @@ gateway-web: ingress: host: gateway.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/gateway-web" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/gateway-web" + tag: 1.0.0 reRoutes: accountService: url: http://eshop-az-authserver @@ -169,8 +169,8 @@ gateway-web-public: ingress: host: gateway-public.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/gateway-web-public" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/gateway-web-public" + tag: 1.0.0 reRoutes: accountService: url: http://eshop-az-authserver @@ -209,8 +209,8 @@ basket: ingress: host: basket.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-basket" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/service-basket" + tag: 1.0.0 # catalog-service sub-chart override catalog: @@ -237,8 +237,8 @@ catalog: ingress: host: catalog.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-catalog" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/service-catalog" + tag: 1.0.0 # ordering-service sub-chart override ordering: @@ -260,9 +260,8 @@ ordering: ingress: host: order.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-ordering" - tag: 1.0.5 - + repository: "ghcr.io/volosoft/eshoponabp/service-ordering" + tag: 1.0.1 # payment-service sub-chart override payment: config: @@ -283,8 +282,8 @@ payment: ingress: host: payment.eshoponabp.com image: - repository: "volocr.azurecr.io/eshoponabp/service-payment" - tag: 1.0.5 + repository: "ghcr.io/volosoft/eshoponabp/service-payment" + tag: 1.0.0 # Default values for eshoponabp. # This is a YAML-formatted file. From 6eaba848a3b136999f27a3d03988211bba117264 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 19 Oct 2022 18:25:36 -0400 Subject: [PATCH 07/32] Updated keycloak migrator --- .../DbMigratorHostedService.cs | 1 - .../EShopOnAbp.Keycloak.DbMigrator.csproj | 3 +- .../EShopOnAbpDbMigratorModule.cs | 16 ++-- .../KeyCloakDataSeeder.cs | 21 ----- .../Keycloak/KeycloakClientOptions.cs | 6 -- .../Keycloak/KeycloakService.cs | 94 ------------------- .../Keycloak/Models/AccessTokenResult.cs | 16 ---- .../KeycloakClientOptions.cs | 9 ++ .../KeycloakDataSeeder.cs | 90 ++++++++++++++++++ .../appsettings.json | 7 +- 10 files changed, 116 insertions(+), 147 deletions(-) delete mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs delete mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs delete mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs delete mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakClientOptions.cs create mode 100644 shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs index ce020de4..d28e0ecf 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/DbMigratorHostedService.cs @@ -1,6 +1,5 @@ using System.Threading; using System.Threading.Tasks; -using EShopOnAbp.DbMigrator.Keycloak; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj index 98834c63..a1d4a9e3 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj @@ -8,8 +8,7 @@ - - + diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs index f739f1e6..fcdb8df2 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbpDbMigratorModule.cs @@ -1,5 +1,4 @@ -using EShopOnAbp.DbMigrator.Keycloak; -using EShopOnAbp.Shared.Hosting; +using EShopOnAbp.Shared.Hosting; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; @@ -13,9 +12,14 @@ public class EShopOnAbpDbMigratorModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - - context.Services.AddHttpClient(KeycloakService.HttpClientName); - - Configure(configuration); + + Configure(options => + { + options.Url = configuration["Keycloak:url"]; + options.AdminUserName = configuration["Keycloak:adminUsername"]; + options.AdminPassword = configuration["Keycloak:adminPassword"]; + options.RealmName = configuration["Keycloak:realmName"]; + } + ); } } \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs deleted file mode 100644 index abd7dcfa..00000000 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeyCloakDataSeeder.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; -using EShopOnAbp.DbMigrator.Keycloak; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; - -namespace EShopOnAbp.DbMigrator; - -public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency -{ - private readonly KeycloakService _keycloakService; - - public KeyCloakDataSeeder(KeycloakService keycloakService) - { - _keycloakService = keycloakService; - } - - public async Task SeedAsync(DataSeedContext context) - { - var result = await _keycloakService.GetAdminAccessTokenAsync("master"); - } -} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs deleted file mode 100644 index 417638d7..00000000 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakClientOptions.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace EShopOnAbp.DbMigrator.Keycloak; - -public class KeycloakClientOptions -{ - -} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs deleted file mode 100644 index 7a8c9a70..00000000 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/KeycloakService.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using EShopOnAbp.DbMigrator.Keycloak.Models; -using Microsoft.Extensions.Logging; -using Volo.Abp.DependencyInjection; - -namespace EShopOnAbp.DbMigrator.Keycloak; - -public class KeycloakService : ITransientDependency -{ - public const string HttpClientName = "KeycloakServiceHttpClientName"; - - // TODO: Option - public const string BaseUrl = "http://localhost:8080/admin/realms"; - public const string AdminClientId = "admin-cli"; - public const string AdminUserName = "admin"; - public const string AdminPassword = "1q2w3E*"; - - private readonly ILogger _logger; - private readonly IHttpClientFactory _clientFactory; - - public KeycloakService(IHttpClientFactory clientFactory, ILogger logger) - { - _clientFactory = clientFactory; - _logger = logger; - } - - // public async Task CreateClientAsync(string realm, Client client) - // { - // HttpResponseMessage response = await InternalCreateClientAsync(realm, client).ConfigureAwait(false); - // - // var locationPathAndQuery = response.Headers.Location.PathAndQuery; - // var clientId = response.IsSuccessStatusCode - // ? locationPathAndQuery.Substring(locationPathAndQuery.LastIndexOf("/", StringComparison.Ordinal) + 1) - // : null; - // return clientId; - // } - - private HttpClient CreateKeycloakApiHttpClient(string realm) - { - var httpClient = _clientFactory.CreateClient(HttpClientName); - httpClient.BaseAddress = new Uri(BaseUrl); - - return httpClient; - } - - private async Task CreateKeycloakApiHttpClientAsync(string realm, string token = null) - { - var httpClient = CreateKeycloakApiHttpClient(realm); - httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); - if (!string.IsNullOrEmpty(token)) - { - var accessToken = await GetAdminAccessTokenAsync(realm); - httpClient.DefaultRequestHeaders.Authorization = - new System.Net.Http.Headers.AuthenticationHeaderValue($"Bearer", $"{accessToken}"); - } - - return httpClient; - } - - public async Task GetAdminAccessTokenAsync(string realm) - { - var httpClient = _clientFactory.CreateClient(HttpClientName); - httpClient.BaseAddress = new Uri(BaseUrl); - - var result = string.Empty; - - var formContent = new FormUrlEncodedContent(new[] - { - new KeyValuePair("client_id", AdminClientId), - new KeyValuePair("username", AdminUserName), - new KeyValuePair("password", AdminPassword), - new KeyValuePair("grant_type", "password") - }); - - var httpResponseMessage = - await httpClient.PostAsync($"/realms/{realm}/protocol/openid-connect/token", formContent); - - if (httpResponseMessage.IsSuccessStatusCode) - { - var response = await httpResponseMessage.Content.ReadFromJsonAsync(); - result = response?.AccessToken; - } - - return result; - } -} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs deleted file mode 100644 index 83d2266b..00000000 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/Keycloak/Models/AccessTokenResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace EShopOnAbp.DbMigrator.Keycloak.Models; - -public class AccessTokenResult -{ - [JsonPropertyName("access_token")] public string AccessToken { get; set; } - [JsonPropertyName("expires_in")] public int Expiration { get; set; } - [JsonPropertyName("refresh_token")] public string RefreshToken { get; set; } - - [JsonPropertyName("refresh_expires_in")] - public int RefreshExpiration { get; set; } - - [JsonPropertyName("token_type")] public string TokenType { get; set; } - [JsonPropertyName("scope")] public string Scope { get; set; } -} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakClientOptions.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakClientOptions.cs new file mode 100644 index 00000000..6c24a9b8 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakClientOptions.cs @@ -0,0 +1,9 @@ +namespace EShopOnAbp.DbMigrator; + +public class KeycloakClientOptions +{ + public string Url { get; set; } + public string AdminUserName { get; set; } + public string AdminPassword { get; set; } + public string RealmName { get; set; } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs new file mode 100644 index 00000000..cda47f15 --- /dev/null +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Keycloak.Net; +using Keycloak.Net.Models.Clients; +using Microsoft.Extensions.Options; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace EShopOnAbp.DbMigrator; + +public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency +{ + private readonly KeycloakClient _keycloakClient; + private readonly KeycloakClientOptions _keycloakOptions; + + public KeyCloakDataSeeder(IOptions keycloakClientOptions) + { + _keycloakOptions = keycloakClientOptions.Value; + + _keycloakClient = new KeycloakClient( + _keycloakOptions.Url, + _keycloakOptions.AdminUserName, + _keycloakOptions.AdminPassword + ); + } + + public async Task SeedAsync(DataSeedContext context) + { + await UpdateAdminUserAsync(); + await CreateClientsAsync(); + } + + private async Task CreateClientsAsync() + { + await CreatePublicWebClientAsync(); + } + + private async Task CreatePublicWebClientAsync() + { + var publicWebClient = (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: "PublicWeb")) + .FirstOrDefault(); + + if (publicWebClient == null) + { + publicWebClient = new Client() + { + ClientId = "PublicWeb", + Name = "Public Web Application", + Protocol = "openid-connect", + Enabled = true, + BaseUrl = "https://localhost:44335/", + RedirectUris = new List + { + "https://localhost:44335/signin-oidc" + }, + FrontChannelLogout = true, + PublicClient = true + }; + publicWebClient.Attributes = new Dictionary + { + { "post.logout.redirect.uris", "https://localhost:44335/signout-callback-oidc" } + }; + + await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); + } + + } + + private async Task UpdateAdminUserAsync() + { + var users = await _keycloakClient.GetUsersAsync(_keycloakOptions.RealmName, username: "admin"); + var adminUser = users.FirstOrDefault(); + if (adminUser == null) + { + throw new Exception( + "Keycloak admin user is not provided, check if KEYCLOAK_ADMIN environment variable is passed properly."); + } + + if (string.IsNullOrEmpty(adminUser.Email)) + { + adminUser.Email = "admin@abp.io"; + adminUser.FirstName = "admin"; + adminUser.EmailVerified = true; + + await _keycloakClient.UpdateUserAsync(_keycloakOptions.RealmName, adminUser.Id, adminUser); + } + } +} \ No newline at end of file diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json index 077404aa..2da323d1 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json @@ -1,3 +1,8 @@ { - + "Keycloak": { + "url": "http://localhost:8080", + "adminUsername": "admin", + "adminPassword": "1q2w3E*", + "realmName": "master" + } } \ No newline at end of file From 25c672a46802c3df75de4ad901fc6b89a4ae0be8 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 02:43:02 -0400 Subject: [PATCH 08/32] updated public web application --- .../EShopOnAbpPublicWebModule.cs | 26 ++++--------------- .../src/EShopOnAbp.PublicWeb/appsettings.json | 6 ++--- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index a0aec3a1..8322f836 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -143,27 +143,10 @@ public class EShopOnAbpPublicWebModule : AbpModule .AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromDays(365); }) .AddAbpOpenIdConnect("oidc", options => { - /* - * ASP.NET core uses the http://*:5000 and https://*:5001 ports for default communication with the OIDC middleware - * The app requires load balancing services to work with :80 or :443 - * These needs to be added to the keycloak client, in order for the redirect to work. - * If you however intend to use the app by itself then, - * Change the ports in launchsettings.json, but beware to also change the options.CallbackPath and options.SignedOutCallbackPath! - * Use LB services whenever possible, to reduce the config hazzle :) - */ - - //Use default signin scheme - // options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - //Keycloak server - options.Authority = configuration["Keycloak:ServerRealm"]; - //Keycloak client ID + options.Authority = configuration["AuthServer:Authority"]; options.ClientId = configuration["Keycloak:ClientId"]; - //Keycloak client secret - // options.ClientSecret = configuration["Keycloak:ClientSecret"]; - //Keycloak .wellknown config origin to fetch config - options.MetadataAddress = configuration["Keycloak:Metadata"]; - //Require keycloak to use SSL - options.RequireHttpsMetadata = false; + options.MetadataAddress = configuration["AuthServer:MetaAddress"]; + options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("openid"); options.Scope.Add("profile"); @@ -171,7 +154,8 @@ public class EShopOnAbpPublicWebModule : AbpModule options.Scope.Add("phone"); options.Scope.Add("roles"); options.Scope.Add("offline_access"); - //Save the token + // options.Scope.Add("AdministrationService"); // Audiences couldn't be seeded -> outdated library + options.SaveTokens = true; //Token response type, will sometimes need to be changed to IdToken, depending on config. options.ResponseType = OpenIdConnectResponseType.Code; diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json index e82d3b47..4f8d0a7f 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json @@ -36,12 +36,12 @@ "Url": "http://localhost:9200" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "ClientId": "PublicWeb", "ClientSecret": "1q2w3e*", "IsOnProd": "false", - "MetaAddress": "https://localhost:44330" + "MetaAddress": "http://localhost:8080/realms/master/.well-known/openid-configuration" }, "Keycloak": { "ServerRealm": "http://localhost:8080/realms/master", From 8d6c94726b16caa63d2e365ea5ce19c17c56afec Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 02:43:34 -0400 Subject: [PATCH 09/32] updated service authority configurations --- services/basket/src/EShopOnAbp.BasketService/appsettings.json | 4 ++-- .../EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json | 4 ++-- .../EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json | 4 ++-- .../EShopOnAbp.OrderingService.HttpApi.Host/appsettings.json | 4 ++-- .../EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/services/basket/src/EShopOnAbp.BasketService/appsettings.json b/services/basket/src/EShopOnAbp.BasketService/appsettings.json index 93adbecc..983d031c 100644 --- a/services/basket/src/EShopOnAbp.BasketService/appsettings.json +++ b/services/basket/src/EShopOnAbp.BasketService/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, diff --git a/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json b/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json index 645ce941..2a8273b1 100644 --- a/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json +++ b/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335,http://localhost:4200" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, diff --git a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json index 9678ab64..014033f8 100644 --- a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json +++ b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, diff --git a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/appsettings.json b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/appsettings.json index 5d6b54e1..865a6130 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/appsettings.json +++ b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json index 83d05c81..93582be1 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, From 3849732fd40c47843bbd24de5407f7fc3324a9cf Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 02:45:48 -0400 Subject: [PATCH 10/32] Disabled audience validation for microservices --- .../EShopOnAbpSharedHostingMicroservicesModule.cs | 1 + .../JwtBearerConfigurationHelper.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/shared/EShopOnAbp.Shared.Hosting.Microservices/EShopOnAbpSharedHostingMicroservicesModule.cs b/shared/EShopOnAbp.Shared.Hosting.Microservices/EShopOnAbpSharedHostingMicroservicesModule.cs index e497d6d5..fdad69fd 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Microservices/EShopOnAbpSharedHostingMicroservicesModule.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Microservices/EShopOnAbpSharedHostingMicroservicesModule.cs @@ -29,6 +29,7 @@ public class EShopOnAbpSharedHostingMicroservicesModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; var configuration = context.Services.GetConfiguration(); Configure(options => diff --git a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs index b00229f1..0cc48603 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; using System; +using Microsoft.IdentityModel.Tokens; using Volo.Abp.Modularity; namespace EShopOnAbp.Shared.Hosting.Microservices; @@ -19,6 +20,10 @@ public static class JwtBearerConfigurationHelper options.Authority = configuration["AuthServer:Authority"]; options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); options.Audience = audience; + options.TokenValidationParameters = new TokenValidationParameters() + { + ValidateAudience = false //Disabled since seeding audience is not possible with the current keycloak.net library version + }; }); } } \ No newline at end of file From 50857b2401791142626e76e74e4f5a56c05a25a0 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 02:47:12 -0400 Subject: [PATCH 11/32] Added client scope creation --- .../KeycloakDataSeeder.cs | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index cda47f15..46b93c22 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Threading.Tasks; using Keycloak.Net; using Keycloak.Net.Models.Clients; +using Keycloak.Net.Models.ClientScopes; +using Keycloak.Net.Models.ProtocolMappers; using Microsoft.Extensions.Options; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; @@ -29,9 +31,65 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency public async Task SeedAsync(DataSeedContext context) { await UpdateAdminUserAsync(); + await CreateClientScopesAsync(); await CreateClientsAsync(); } + private async Task CreateClientScopesAsync() + { + await CreateScopeAsync("AdministrationService"); + await CreateScopeAsync("IdentityService"); + await CreateScopeAsync("BasketService"); + await CreateScopeAsync("CatalogService"); + await CreateScopeAsync("OrderingService"); + await CreateScopeAsync("PaymentService"); + await CreateScopeAsync("CmskitService"); + } + + private async Task CreateScopeAsync(string scopeName) + { + var scope = (await _keycloakClient.GetClientScopesAsync(_keycloakOptions.RealmName)) + .FirstOrDefault(q => q.Name == scopeName); + + if (scope == null) + { + scope = new ClientScope() + { + Name = scopeName, + Description = scopeName + " scope", + Protocol = "openid-connect", + Attributes = new Attributes + { + ConsentScreenText = scopeName, + DisplayOnConsentScreen = "true", + IncludeInTokenScope = "true" + }, + ProtocolMappers = new List() + { + new ProtocolMapper() + { + Name = scopeName, + Protocol = "openid-connect", + _ProtocolMapper = "oidc-audience-mapper", + // Config = new Dictionary() + // { + // {"id.token.claim", "false"}, + // {"access.token.claim", "true"}, + // {"included.custom.audience", scopeName} + // } + Config = new Config() // This should be dictionary -> Outdated library + { + AccessTokenClaim = "true", + IdTokenClaim = "false" + } + } + } + }; + + await _keycloakClient.CreateClientScopeAsync(_keycloakOptions.RealmName, scope); + } + } + private async Task CreateClientsAsync() { await CreatePublicWebClientAsync(); @@ -62,10 +120,9 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency { { "post.logout.redirect.uris", "https://localhost:44335/signout-callback-oidc" } }; - + await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); } - } private async Task UpdateAdminUserAsync() From c79dfa3a4e24145d9e184efdb8ece5d8affcd8b2 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 23:20:05 -0400 Subject: [PATCH 12/32] updated appsettings configuration --- .../EShopOnAbpPublicWebModule.cs | 34 +++++-------------- .../src/EShopOnAbp.PublicWeb/appsettings.json | 1 - 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index 8322f836..69deb0fb 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -144,7 +144,7 @@ public class EShopOnAbpPublicWebModule : AbpModule .AddAbpOpenIdConnect("oidc", options => { options.Authority = configuration["AuthServer:Authority"]; - options.ClientId = configuration["Keycloak:ClientId"]; + options.ClientId = configuration["AuthServer:ClientId"]; options.MetadataAddress = configuration["AuthServer:MetaAddress"]; options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); options.GetClaimsFromUserInfoEndpoint = true; @@ -154,7 +154,14 @@ public class EShopOnAbpPublicWebModule : AbpModule options.Scope.Add("phone"); options.Scope.Add("roles"); options.Scope.Add("offline_access"); - // options.Scope.Add("AdministrationService"); // Audiences couldn't be seeded -> outdated library + // Audiences couldn't be seeded -> TODO: Update when library is updated + // options.Scope.Add("AccountService"); + // options.Scope.Add("AdministrationService"); + // options.Scope.Add("BasketService"); + // options.Scope.Add("CatalogService"); + // options.Scope.Add("PaymentService"); + // options.Scope.Add("OrderingService"); + // options.Scope.Add("CmskitService"); options.SaveTokens = true; //Token response type, will sometimes need to be changed to IdToken, depending on config. @@ -177,29 +184,6 @@ public class EShopOnAbpPublicWebModule : AbpModule options.ClaimActions.RemoveDuplicate(AbpClaimTypes.UserName); } }); - // .AddAbpOpenIdConnect("oidc", options => - // { - // options.Authority = configuration["AuthServer:Authority"]; - // options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); - // options.ResponseType = OpenIdConnectResponseType.CodeIdToken; - // - // options.ClientId = configuration["AuthServer:ClientId"]; - // options.ClientSecret = configuration["AuthServer:ClientSecret"]; - // - // options.SaveTokens = true; - // options.GetClaimsFromUserInfoEndpoint = true; - // - // options.Scope.Add("role"); - // options.Scope.Add("email"); - // options.Scope.Add("phone"); - // options.Scope.Add("AccountService"); - // options.Scope.Add("AdministrationService"); - // options.Scope.Add("BasketService"); - // options.Scope.Add("CatalogService"); - // options.Scope.Add("PaymentService"); - // options.Scope.Add("OrderingService"); - // options.Scope.Add("CmskitService"); - // }); if (Convert.ToBoolean(configuration["AuthServer:IsOnProd"])) { context.Services.Configure("oidc", options => diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json index 4f8d0a7f..c339e14c 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json @@ -39,7 +39,6 @@ "Authority": "http://localhost:8080/realms/master", "RequireHttpsMetadata": "false", "ClientId": "PublicWeb", - "ClientSecret": "1q2w3e*", "IsOnProd": "false", "MetaAddress": "http://localhost:8080/realms/master/.well-known/openid-configuration" }, From 293543ad8f986957bdeffb629650dfeb0212d681 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Thu, 20 Oct 2022 23:21:07 -0400 Subject: [PATCH 13/32] Added swagger client and configurations --- .../AdministrationServiceHttpApiHostModule.cs | 2 +- .../appsettings.json | 3 +- .../KeycloakDataSeeder.cs | 130 +++++++++++++++--- .../appsettings.json | 38 +++++ 4 files changed, 154 insertions(+), 19 deletions(-) diff --git a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs index 9b349ff8..7ecb1575 100644 --- a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs +++ b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs @@ -91,7 +91,7 @@ public class AdministrationServiceHttpApiHostModule : AbpModule var configuration = context.ServiceProvider.GetRequiredService(); options.SwaggerEndpoint("/swagger/v1/swagger.json", "Administration Service API"); options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); - options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); + // options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); }); app.UseAbpSerilogEnrichers(); app.UseAuditing(); diff --git a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json index 620ba213..9368fc53 100644 --- a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json +++ b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json @@ -6,8 +6,7 @@ "AuthServer": { "Authority": "http://localhost:8080/realms/master", "RequireHttpsMetadata": "false", - "SwaggerClientId": "WebGateway_Swagger", - "SwaggerClientSecret": "1q2w3e*" + "SwaggerClientId": "SwaggerClient" }, "RemoteServices": { "AbpIdentity": { diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index 46b93c22..223178e8 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -6,6 +6,8 @@ using Keycloak.Net; using Keycloak.Net.Models.Clients; using Keycloak.Net.Models.ClientScopes; using Keycloak.Net.Models.ProtocolMappers; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; @@ -16,9 +18,13 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency { private readonly KeycloakClient _keycloakClient; private readonly KeycloakClientOptions _keycloakOptions; + private readonly ILogger _logger; + private readonly IConfiguration _configuration; - public KeyCloakDataSeeder(IOptions keycloakClientOptions) + public KeyCloakDataSeeder(IOptions keycloakClientOptions, ILogger logger, IConfiguration configuration) { + _logger = logger; + _configuration = configuration; _keycloakOptions = keycloakClientOptions.Value; _keycloakClient = new KeycloakClient( @@ -37,6 +43,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private async Task CreateClientScopesAsync() { + await CreateScopeAsync("AccountService"); await CreateScopeAsync("AdministrationService"); await CreateScopeAsync("IdentityService"); await CreateScopeAsync("BasketService"); @@ -50,10 +57,10 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency { var scope = (await _keycloakClient.GetClientScopesAsync(_keycloakOptions.RealmName)) .FirstOrDefault(q => q.Name == scopeName); - + if (scope == null) { - scope = new ClientScope() + scope = new ClientScope { Name = scopeName, Description = scopeName + " scope", @@ -71,17 +78,17 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = scopeName, Protocol = "openid-connect", _ProtocolMapper = "oidc-audience-mapper", - // Config = new Dictionary() - // { - // {"id.token.claim", "false"}, - // {"access.token.claim", "true"}, - // {"included.custom.audience", scopeName} - // } - Config = new Config() // This should be dictionary -> Outdated library + Config = new Dictionary() { - AccessTokenClaim = "true", - IdTokenClaim = "false" + { "id.token.claim", "false" }, + { "access.token.claim", "true" }, + { "included.custom.audience", scopeName } } + // Config = new Config() // This should be dictionary -> Outdated library + // { + // AccessTokenClaim = "true", + // IdTokenClaim = "false" + // } } } }; @@ -93,6 +100,57 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private async Task CreateClientsAsync() { await CreatePublicWebClientAsync(); + await CreateSwaggerClientAsync(); + } + + private async Task CreateSwaggerClientAsync() + { + var swaggerClient = (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: "SwaggerClient")) + .FirstOrDefault(); + + if (swaggerClient == null) + { + var webGatewaySwaggerRootUrl = _configuration[$"Clients:WebGateway:RootUrl"].TrimEnd('/'); + var publicWebGatewayRootUrl = _configuration[$"Clients:PublicWebGateway:RootUrl"].TrimEnd('/'); + var accountServiceRootUrl = _configuration[$"Clients:AccountService:RootUrl"].TrimEnd('/'); + var identityServiceRootUrl = _configuration[$"Clients:IdentityService:RootUrl"].TrimEnd('/'); + var administrationServiceRootUrl = _configuration[$"Clients:AdministrationService:RootUrl"].TrimEnd('/'); + var catalogServiceRootUrl = _configuration[$"Clients:CatalogService:RootUrl"].TrimEnd('/'); + var basketServiceRootUrl = _configuration[$"Clients:BasketService:RootUrl"].TrimEnd('/'); + var orderingServiceRootUrl = _configuration[$"Clients:OrderingService:RootUrl"].TrimEnd('/'); + var paymentServiceRootUrl = _configuration[$"Clients:PaymentService:RootUrl"].TrimEnd('/'); + var cmskitServiceRootUrl = _configuration[$"Clients:CmskitService:RootUrl"].TrimEnd('/'); + + swaggerClient = new Client + { + ClientId = "SwaggerClient", + Name = "Swagger Client Application", + Protocol = "openid-connect", + Enabled = true, + // BaseUrl = "https://localhost:44335/", + RedirectUris = new List + { + $"{webGatewaySwaggerRootUrl}/swagger/oauth2-redirect.html", // WebGateway redirect uri + $"{publicWebGatewayRootUrl}/swagger/oauth2-redirect.html", // PublicWebGateway redirect uri + $"{accountServiceRootUrl}/swagger/oauth2-redirect.html", // AccountService redirect uri + $"{identityServiceRootUrl}/swagger/oauth2-redirect.html", // IdentityService redirect uri + $"{administrationServiceRootUrl}/swagger/oauth2-redirect.html", // AdministrationService redirect uri + $"{catalogServiceRootUrl}/swagger/oauth2-redirect.html", // CatalogService redirect uri + $"{basketServiceRootUrl}/swagger/oauth2-redirect.html", // BasketService redirect uri + $"{orderingServiceRootUrl}/swagger/oauth2-redirect.html", // OrderingService redirect uri + $"{paymentServiceRootUrl}/swagger/oauth2-redirect.html", // PaymentService redirect uri + $"{cmskitServiceRootUrl}/swagger/oauth2-redirect.html" // CmskitService redirect uri + }, + FrontChannelLogout = true, + PublicClient = true + }; + swaggerClient.Attributes = new Dictionary + { + { "post.logout.redirect.uris", "https://localhost:44335/signout-callback-oidc" } + }; + + await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, swaggerClient); + } } private async Task CreatePublicWebClientAsync() @@ -102,27 +160,64 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency if (publicWebClient == null) { - publicWebClient = new Client() + var publicWebRootUrl = _configuration[$"Clients:PublicWeb:RootUrl"]; + publicWebClient = new Client { ClientId = "PublicWeb", Name = "Public Web Application", Protocol = "openid-connect", Enabled = true, - BaseUrl = "https://localhost:44335/", + BaseUrl = publicWebRootUrl, RedirectUris = new List { - "https://localhost:44335/signin-oidc" + $"{publicWebRootUrl.TrimEnd('/')}/signin-oidc" }, FrontChannelLogout = true, PublicClient = true }; publicWebClient.Attributes = new Dictionary { - { "post.logout.redirect.uris", "https://localhost:44335/signout-callback-oidc" } + { "post.logout.redirect.uris", $"{publicWebRootUrl.TrimEnd('/')}/signout-callback-oidc" } }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); } + + await AddOptionalClientScopesAsync( + "PublicWeb", + new List + { + "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", + "OrderingService", "PaymentService", "CmskitService" + } + ); + } + + private async Task AddOptionalClientScopesAsync(string clientName, List scopes) + { + var client = (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: clientName)) + .FirstOrDefault(); + if (client == null) + { + _logger.LogError($"Couldn't find {clientName}! Could not seed optional scopes!"); + return; + } + + var clientOptionalScopes = + (await _keycloakClient.GetOptionalClientScopesAsync(_keycloakOptions.RealmName, client.Id)).ToList(); + + var clientScopes = (await _keycloakClient.GetClientScopesAsync(_keycloakOptions.RealmName)).ToList(); + + foreach (var scope in scopes) + { + if (!clientOptionalScopes.Any(q => q.Name == scope)) + { + var serviceScope = clientScopes.First(q => q.Name == scope); + _logger.LogInformation($"Seeding {scope} scope to {clientName}."); + await _keycloakClient.UpdateOptionalClientScopeAsync(_keycloakOptions.RealmName, client.Id, + serviceScope.Id); + } + } } private async Task UpdateAdminUserAsync() @@ -131,6 +226,8 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency var adminUser = users.FirstOrDefault(); if (adminUser == null) { + _logger.LogError( + "Keycloak admin user is not provided, check if KEYCLOAK_ADMIN environment variable is passed properly."); throw new Exception( "Keycloak admin user is not provided, check if KEYCLOAK_ADMIN environment variable is passed properly."); } @@ -141,6 +238,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency adminUser.FirstName = "admin"; adminUser.EmailVerified = true; + _logger.LogInformation("Updating admin user with email and first name..."); await _keycloakClient.UpdateUserAsync(_keycloakOptions.RealmName, adminUser.Id, adminUser); } } diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json index 2da323d1..13bcec2d 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/appsettings.json @@ -4,5 +4,43 @@ "adminUsername": "admin", "adminPassword": "1q2w3E*", "realmName": "master" + }, + "Clients": { + "Web": { + "RootUrl": "http://localhost:4200" + }, + "PublicWeb": { + "RootUrl": "https://localhost:44335" + }, + "WebGateway": { + "RootUrl": "https://localhost:44372" + }, + "PublicWebGateway": { + "RootUrl": "https://localhost:44373" + }, + "AccountService": { + "RootUrl": "https://localhost:44330" + }, + "IdentityService": { + "RootUrl": "https://localhost:44351" + }, + "AdministrationService": { + "RootUrl": "https://localhost:44353" + }, + "CatalogService": { + "RootUrl": "https://localhost:44354" + }, + "BasketService": { + "RootUrl": "https://localhost:44355" + }, + "OrderingService": { + "RootUrl": "https://localhost:44356" + }, + "PaymentService": { + "RootUrl": "https://localhost:44357" + }, + "CmskitService": { + "RootUrl": "https://localhost:44358" + } } } \ No newline at end of file From 3ef362f7f249326c0379348de36e089eae5078d5 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 21 Oct 2022 23:08:15 -0400 Subject: [PATCH 14/32] Added angular client --- apps/angular/src/environments/environment.ts | 5 +- .../KeycloakDataSeeder.cs | 66 ++++++++++++++----- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/apps/angular/src/environments/environment.ts b/apps/angular/src/environments/environment.ts index 9c3c768d..243cea14 100644 --- a/apps/angular/src/environments/environment.ts +++ b/apps/angular/src/environments/environment.ts @@ -9,11 +9,12 @@ export const environment = { name: 'EShopOnAbp', }, oAuthConfig: { - issuer: 'https://localhost:44330', + issuer: 'http://localhost:8080/realms/master', redirectUri: baseUrl, clientId: 'Web', responseType: 'code', - scope: 'offline_access openid profile email phone AccountService IdentityService AdministrationService CatalogService OrderingService', + scope: 'offline_access openid profile email phone', + // scope: 'offline_access openid profile email phone AccountService IdentityService AdministrationService CatalogService OrderingService', //TODO: Update when https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged //requireHttps: true, }, apis: { diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index 223178e8..fbc82386 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -100,7 +100,48 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private async Task CreateClientsAsync() { await CreatePublicWebClientAsync(); - await CreateSwaggerClientAsync(); + await CreateSwaggerClientAsync(); // TODO: Test when Volo.Abp.Swashbuckle v6.0.1 is released (https://github.com/abpframework/abp/pull/14409) + await CreateWebClientAsync(); + } + + private async Task CreateWebClientAsync() + { + var webClient = (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: "Web")) + .FirstOrDefault(); + + if (webClient == null) + { + var webRootUrl = _configuration[$"Clients:Web:RootUrl"]; + webClient = new Client + { + ClientId = "Web", + Name = "Angular Back-Office Web Application", + Protocol = "openid-connect", + Enabled = true, + BaseUrl = webRootUrl, + RedirectUris = new List + { + $"{webRootUrl.TrimEnd('/')}" + }, + FrontChannelLogout = true, + PublicClient = true + }; + webClient.Attributes = new Dictionary + { + { "post.logout.redirect.uris", $"{webRootUrl.TrimEnd('/')}" } + }; + + await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, webClient); + //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged + // await AddOptionalClientScopesAsync( + // "PublicWeb", + // new List + // { + // "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", + // "OrderingService", "PaymentService", "CmskitService" + // } + // ); + } } private async Task CreateSwaggerClientAsync() @@ -127,7 +168,6 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = "Swagger Client Application", Protocol = "openid-connect", Enabled = true, - // BaseUrl = "https://localhost:44335/", RedirectUris = new List { $"{webGatewaySwaggerRootUrl}/swagger/oauth2-redirect.html", // WebGateway redirect uri @@ -144,10 +184,6 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency FrontChannelLogout = true, PublicClient = true }; - swaggerClient.Attributes = new Dictionary - { - { "post.logout.redirect.uris", "https://localhost:44335/signout-callback-oidc" } - }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, swaggerClient); } @@ -181,16 +217,16 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); + //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged + // await AddOptionalClientScopesAsync( + // "PublicWeb", + // new List + // { + // "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", + // "OrderingService", "PaymentService", "CmskitService" + // } + // ); } - - await AddOptionalClientScopesAsync( - "PublicWeb", - new List - { - "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", - "OrderingService", "PaymentService", "CmskitService" - } - ); } private async Task AddOptionalClientScopesAsync(string clientName, List scopes) From 8709d2598e12ff2712fb8cf048b4b2348fb1cfcf Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 21 Oct 2022 23:50:44 -0400 Subject: [PATCH 15/32] updated CmskitService configuration for keycloak --- .../EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json index 151dd3ec..2558921d 100644 --- a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json +++ b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json @@ -4,8 +4,8 @@ "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200,https://localhost:44335" }, "AuthServer": { - "Authority": "https://localhost:44330", - "RequireHttpsMetadata": "true", + "Authority": "http://localhost:8080/realms/master", + "RequireHttpsMetadata": "false", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" }, From 7817404531d368073847e36e945551c059366f9f Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Fri, 21 Oct 2022 23:51:21 -0400 Subject: [PATCH 16/32] Updated keycloak data seeder for current keycloak library --- .../EShopOnAbp.Keycloak.DbMigrator.csproj | 1 + .../KeycloakDataSeeder.cs | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj index a1d4a9e3..f7f9c1ba 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj @@ -13,6 +13,7 @@ + diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index fbc82386..a5d9428d 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -78,17 +78,17 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = scopeName, Protocol = "openid-connect", _ProtocolMapper = "oidc-audience-mapper", - Config = new Dictionary() - { - { "id.token.claim", "false" }, - { "access.token.claim", "true" }, - { "included.custom.audience", scopeName } - } - // Config = new Config() // This should be dictionary -> Outdated library + // Config = new Dictionary() //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged // { - // AccessTokenClaim = "true", - // IdTokenClaim = "false" + // { "id.token.claim", "false" }, + // { "access.token.claim", "true" }, + // { "included.custom.audience", scopeName } // } + Config = new Config() // This should be dictionary -> Outdated library + { + AccessTokenClaim = "true", + IdTokenClaim = "false" + } } } }; @@ -132,6 +132,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, webClient); + //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged // await AddOptionalClientScopesAsync( // "PublicWeb", @@ -217,6 +218,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); + //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged // await AddOptionalClientScopesAsync( // "PublicWeb", From 8cbf311b43e11c6627c82e531bfad709da78e7fb Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 22 Oct 2022 00:06:05 -0400 Subject: [PATCH 17/32] removed AccountService scope seed --- shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index a5d9428d..32aff192 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -133,12 +133,12 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, webClient); - //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged + //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged // await AddOptionalClientScopesAsync( // "PublicWeb", // new List // { - // "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", + // "AdministrationService", "IdentityService", "BasketService", "CatalogService", // "OrderingService", "PaymentService", "CmskitService" // } // ); @@ -224,7 +224,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency // "PublicWeb", // new List // { - // "AccountService", "AdministrationService", "IdentityService", "BasketService", "CatalogService", + // "AdministrationService", "IdentityService", "BasketService", "CatalogService", // "OrderingService", "PaymentService", "CmskitService" // } // ); From c4ff32c46ff6c50c6bdfbaaa425d095ba2522710 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 25 Oct 2022 23:54:52 -0400 Subject: [PATCH 18/32] Added keycloak-seeder tye support --- tye.yaml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tye.yaml b/tye.yaml index 0edccd81..de0f4014 100644 --- a/tye.yaml +++ b/tye.yaml @@ -1,13 +1,13 @@ name: EShopOnAbp services: -- name: auth-server - project: apps/auth-server/src/EShopOnAbp.AuthServer/EShopOnAbp.AuthServer.csproj - bindings: - - protocol: https - port: 44330 - env: - - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx - - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 +# - name: auth-server +# project: apps/auth-server/src/EShopOnAbp.AuthServer/EShopOnAbp.AuthServer.csproj +# bindings: +# - protocol: https +# port: 44330 +# env: +# - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx +# - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 - name: identity-service project: services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/EShopOnAbp.IdentityService.HttpApi.Host.csproj @@ -101,4 +101,7 @@ services: port: 44335 env: - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx - - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 \ No newline at end of file + - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 + +- name: keycloak-seeder + project: shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj \ No newline at end of file From 498fc03e8936be9d1ae71e18d3020977e1148346 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 00:43:36 -0400 Subject: [PATCH 19/32] Updated library, added audiences --- .../EShopOnAbpPublicWebModule.cs | 15 +++--- .../EShopOnAbp.Keycloak.DbMigrator.csproj | 3 +- .../KeycloakDataSeeder.cs | 50 ++++++++----------- .../JwtBearerConfigurationHelper.cs | 4 -- 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index b250e7b9..f231a383 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -154,14 +154,13 @@ public class EShopOnAbpPublicWebModule : AbpModule options.Scope.Add("phone"); options.Scope.Add("roles"); options.Scope.Add("offline_access"); - // Audiences couldn't be seeded -> TODO: Update when library is updated - // options.Scope.Add("AccountService"); - // options.Scope.Add("AdministrationService"); - // options.Scope.Add("BasketService"); - // options.Scope.Add("CatalogService"); - // options.Scope.Add("PaymentService"); - // options.Scope.Add("OrderingService"); - // options.Scope.Add("CmskitService"); + + options.Scope.Add("AdministrationService"); + options.Scope.Add("BasketService"); + options.Scope.Add("CatalogService"); + options.Scope.Add("PaymentService"); + options.Scope.Add("OrderingService"); + options.Scope.Add("CmskitService"); options.SaveTokens = true; //Token response type, will sometimes need to be changed to IdToken, depending on config. diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj index f7f9c1ba..47d14f09 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj @@ -8,12 +8,11 @@ - + - diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index 32aff192..80051883 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -43,7 +43,6 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private async Task CreateClientScopesAsync() { - await CreateScopeAsync("AccountService"); await CreateScopeAsync("AdministrationService"); await CreateScopeAsync("IdentityService"); await CreateScopeAsync("BasketService"); @@ -78,16 +77,11 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = scopeName, Protocol = "openid-connect", _ProtocolMapper = "oidc-audience-mapper", - // Config = new Dictionary() //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged - // { - // { "id.token.claim", "false" }, - // { "access.token.claim", "true" }, - // { "included.custom.audience", scopeName } - // } - Config = new Config() // This should be dictionary -> Outdated library + Config = new Dictionary() //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged { - AccessTokenClaim = "true", - IdTokenClaim = "false" + { "id.token.claim", "false" }, + { "access.token.claim", "true" }, + { "included.custom.audience", scopeName } } } } @@ -133,15 +127,14 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, webClient); - //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged - // await AddOptionalClientScopesAsync( - // "PublicWeb", - // new List - // { - // "AdministrationService", "IdentityService", "BasketService", "CatalogService", - // "OrderingService", "PaymentService", "CmskitService" - // } - // ); + await AddOptionalClientScopesAsync( + "PublicWeb", + new List + { + "AdministrationService", "IdentityService", "BasketService", "CatalogService", + "OrderingService", "PaymentService", "CmskitService" + } + ); } } @@ -219,15 +212,14 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); - //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged - // await AddOptionalClientScopesAsync( - // "PublicWeb", - // new List - // { - // "AdministrationService", "IdentityService", "BasketService", "CatalogService", - // "OrderingService", "PaymentService", "CmskitService" - // } - // ); + await AddOptionalClientScopesAsync( + "PublicWeb", + new List + { + "AdministrationService", "IdentityService", "BasketService", "CatalogService", + "OrderingService", "PaymentService", "CmskitService" + } + ); } } @@ -264,8 +256,6 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency var adminUser = users.FirstOrDefault(); if (adminUser == null) { - _logger.LogError( - "Keycloak admin user is not provided, check if KEYCLOAK_ADMIN environment variable is passed properly."); throw new Exception( "Keycloak admin user is not provided, check if KEYCLOAK_ADMIN environment variable is passed properly."); } diff --git a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs index 0cc48603..f87c63f4 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs @@ -20,10 +20,6 @@ public static class JwtBearerConfigurationHelper options.Authority = configuration["AuthServer:Authority"]; options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); options.Audience = audience; - options.TokenValidationParameters = new TokenValidationParameters() - { - ValidateAudience = false //Disabled since seeding audience is not possible with the current keycloak.net library version - }; }); } } \ No newline at end of file From b2cf7ca89e5b6a18c9cdeedb110d49ecfbafc01a Mon Sep 17 00:00:00 2001 From: malik masis Date: Wed, 26 Oct 2022 10:40:39 +0300 Subject: [PATCH 20/32] Applied the temporary solution --- .../Pages/ProductDetail.cshtml.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/ProductDetail.cshtml.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/ProductDetail.cshtml.cs index 32bcbdd0..f8dbf4f6 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/ProductDetail.cshtml.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/ProductDetail.cshtml.cs @@ -29,8 +29,17 @@ namespace EShopOnAbp.PublicWeb.Pages public async Task OnGet(Guid id) { - IsPurschased = (await _orderAppService.GetMyOrdersAsync(new GetMyOrdersInput())).Any(p => p.Items.Any(p => p.ProductId == id)); Product = await _productAppService.GetAsync(id); + + try + { + IsPurschased = (await _orderAppService.GetMyOrdersAsync(new GetMyOrdersInput())).Any(p => p.Items.Any(p => p.ProductId == id)); + } + catch (Exception e) + { + IsPurschased = false; + Console.WriteLine(e); + } } } } \ No newline at end of file From b30c78b86a69dd0a106346934c66d5188805ec5c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 03:54:47 -0400 Subject: [PATCH 21/32] added tye configration --- tye.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tye.yaml b/tye.yaml index de0f4014..73ac37d4 100644 --- a/tye.yaml +++ b/tye.yaml @@ -94,14 +94,14 @@ services: - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 -- name: public-web - project: apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj - bindings: - - protocol: https - port: 44335 - env: - - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx - - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 +# - name: public-web +# project: apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj +# bindings: +# - protocol: https +# port: 44335 +# env: +# - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx +# - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 - name: keycloak-seeder project: shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj \ No newline at end of file From 5931c61b30d3821ec523ea2490a30ead6ebdab57 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 03:56:17 -0400 Subject: [PATCH 22/32] updated cors configurations --- .../appsettings.json | 2 +- services/basket/src/EShopOnAbp.BasketService/appsettings.json | 2 +- .../src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json | 2 +- .../src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json | 2 +- .../IdentityServiceHttpApiHostModule.cs | 2 +- .../EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json index 9368fc53..6794a32d 100644 --- a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json +++ b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json @@ -1,7 +1,7 @@ { "App": { "SelfUrl": "https://localhost:44353", - "CorsOrigins": "https://localhost:44372,https://localhost:44373" + "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200" }, "AuthServer": { "Authority": "http://localhost:8080/realms/master", diff --git a/services/basket/src/EShopOnAbp.BasketService/appsettings.json b/services/basket/src/EShopOnAbp.BasketService/appsettings.json index 983d031c..7ef6ff5f 100644 --- a/services/basket/src/EShopOnAbp.BasketService/appsettings.json +++ b/services/basket/src/EShopOnAbp.BasketService/appsettings.json @@ -1,7 +1,7 @@ { "App": { "SelfUrl": "https://localhost:44355", - "CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335" + "CorsOrigins": "https://localhost:44372,https://localhost:44373,,http://localhost:4200" }, "AuthServer": { "Authority": "http://localhost:8080/realms/master", diff --git a/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json b/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json index 2a8273b1..7a8b88c1 100644 --- a/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json +++ b/services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/appsettings.json @@ -1,7 +1,7 @@ { "App": { "SelfUrl": "https://localhost:44354", - "CorsOrigins": "https://localhost:44372,https://localhost:44373,https://localhost:44335,http://localhost:4200" + "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200" }, "AuthServer": { "Authority": "http://localhost:8080/realms/master", diff --git a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json index 2558921d..750d9c24 100644 --- a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json +++ b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json @@ -1,7 +1,7 @@ { "App": { "SelfUrl": "https://localhost:44358", - "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200,https://localhost:44335" + "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200" }, "AuthServer": { "Authority": "http://localhost:8080/realms/master", diff --git a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs index 98ed74e0..1d837bb5 100644 --- a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs +++ b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs @@ -40,7 +40,7 @@ public class IdentityServiceHttpApiHostModule : AbpModule { { "IdentityService", "Identity Service API" } }, - apiTitle: "IdentityService Gateway API" + apiTitle: "IdentityService API" ); diff --git a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json index 014033f8..9cdfa28f 100644 --- a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json +++ b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json @@ -1,7 +1,7 @@ { "App": { "SelfUrl": "https://localhost:44351", - "CorsOrigins": "https://localhost:44372,https://localhost:44373" + "CorsOrigins": "https://localhost:44372,https://localhost:44373,http://localhost:4200" }, "AuthServer": { "Authority": "http://localhost:8080/realms/master", From 84cc16ece6191253bb8d1891bb6e10a3ff2245f7 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 03:57:25 -0400 Subject: [PATCH 23/32] removed unnecessery usings --- .../EShopOnAbpPublicWebModule.cs | 24 ++++++++++--------- .../JwtBearerConfigurationHelper.cs | 1 - 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index f231a383..b0078b9b 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -72,8 +72,6 @@ namespace EShopOnAbp.PublicWeb; typeof(CmskitServiceHttpApiClientModule), typeof(CmsKitDomainModule), typeof(CmsKitPublicWebModule) - - )] public class EShopOnAbpPublicWebModule : AbpModule { @@ -147,6 +145,7 @@ public class EShopOnAbpPublicWebModule : AbpModule options.ClientId = configuration["AuthServer:ClientId"]; options.MetadataAddress = configuration["AuthServer:MetaAddress"]; options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("openid"); options.Scope.Add("profile"); @@ -154,17 +153,16 @@ public class EShopOnAbpPublicWebModule : AbpModule options.Scope.Add("phone"); options.Scope.Add("roles"); options.Scope.Add("offline_access"); - + options.Scope.Add("AdministrationService"); options.Scope.Add("BasketService"); options.Scope.Add("CatalogService"); options.Scope.Add("PaymentService"); options.Scope.Add("OrderingService"); options.Scope.Add("CmskitService"); - + options.SaveTokens = true; - //Token response type, will sometimes need to be changed to IdToken, depending on config. - options.ResponseType = OpenIdConnectResponseType.Code; + //SameSite is needed for Chrome/Firefox, as they will give http error 500 back, if not set to unspecified. // options.NonceCookie.SameSite = SameSiteMode.Unspecified; // options.CorrelationCookie.SameSite = SameSiteMode.Unspecified; @@ -175,7 +173,7 @@ public class EShopOnAbpPublicWebModule : AbpModule // RoleClaimType = ClaimTypes.Role, // ValidateIssuer = true // }; - + if (AbpClaimTypes.UserName != "preferred_username") { options.ClaimActions.MapJsonKey(AbpClaimTypes.UserName, "preferred_username"); @@ -194,18 +192,21 @@ public class EShopOnAbpPublicWebModule : AbpModule options.Events.OnRedirectToIdentityProvider = async ctx => { // Intercept the redirection so the browser navigates to the right URL in your host - ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/authorize"; + ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + + "connect/authorize"; if (previousOnRedirectToIdentityProvider != null) { await previousOnRedirectToIdentityProvider(ctx); } }; - var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut; + var previousOnRedirectToIdentityProviderForSignOut = + options.Events.OnRedirectToIdentityProviderForSignOut; options.Events.OnRedirectToIdentityProviderForSignOut = async ctx => { // Intercept the redirection for signout so the browser navigates to the right URL in your host - ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + "connect/endsession"; + ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"].EnsureEndsWith('/') + + "connect/endsession"; if (previousOnRedirectToIdentityProviderForSignOut != null) { @@ -250,7 +251,8 @@ public class EShopOnAbpPublicWebModule : AbpModule private void ConfigureBasketHttpClient(ServiceConfigurationContext context) { context.Services.AddStaticHttpClientProxies( - typeof(BasketServiceContractsModule).Assembly, remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName + typeof(BasketServiceContractsModule).Assembly, + remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName ); Configure(options => diff --git a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs index f87c63f4..b00229f1 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Microservices/JwtBearerConfigurationHelper.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; using System; -using Microsoft.IdentityModel.Tokens; using Volo.Abp.Modularity; namespace EShopOnAbp.Shared.Hosting.Microservices; From adfc00eaa0e3468a17714af86e21a0b758db070e Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 03:57:51 -0400 Subject: [PATCH 24/32] added scope and role mapping seeding --- .../KeycloakDataSeeder.cs | 64 ++++++++++++++----- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs index 80051883..2956e3d4 100644 --- a/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs +++ b/shared/EShopOnAbp.Keycloak.DbMigrator/KeycloakDataSeeder.cs @@ -21,7 +21,8 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private readonly ILogger _logger; private readonly IConfiguration _configuration; - public KeyCloakDataSeeder(IOptions keycloakClientOptions, ILogger logger, IConfiguration configuration) + public KeyCloakDataSeeder(IOptions keycloakClientOptions, ILogger logger, + IConfiguration configuration) { _logger = logger; _configuration = configuration; @@ -37,10 +38,38 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency public async Task SeedAsync(DataSeedContext context) { await UpdateAdminUserAsync(); + await CreateRoleMapperAsync(); await CreateClientScopesAsync(); await CreateClientsAsync(); } + private async Task CreateRoleMapperAsync() + { + var roleScope = (await _keycloakClient.GetClientScopesAsync(_keycloakOptions.RealmName)) + .FirstOrDefault(q => q.Name == "roles"); + if (roleScope == null) + return; + + if (!roleScope.ProtocolMappers.Any(q => q.Name == "roles")) + { + await _keycloakClient.CreateProtocolMapperAsync(_keycloakOptions.RealmName, roleScope.Id, + new ProtocolMapper() + { + Name = "roles", + Protocol = "openid-connect", + _ProtocolMapper = "oidc-usermodel-realm-role-mapper", + Config = new Dictionary() + { + { "access.token.claim", "true" }, + { "id.token.claim", "true" }, + { "claim.name", "roles" }, + { "multivalued", "true" }, + { "userinfo.token.claim", "true" }, + } + }); + } + } + private async Task CreateClientScopesAsync() { await CreateScopeAsync("AdministrationService"); @@ -77,12 +106,15 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = scopeName, Protocol = "openid-connect", _ProtocolMapper = "oidc-audience-mapper", - Config = new Dictionary() //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged - { - { "id.token.claim", "false" }, - { "access.token.claim", "true" }, - { "included.custom.audience", scopeName } - } + Config = + new + Dictionary() //TODO: Update when //https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged + { + { "id.token.claim", "false" }, + { "access.token.claim", "true" }, + { "included.custom.audience", scopeName } + } } } }; @@ -126,9 +158,9 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, webClient); - + await AddOptionalClientScopesAsync( - "PublicWeb", + "Web", new List { "AdministrationService", "IdentityService", "BasketService", "CatalogService", @@ -140,9 +172,10 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency private async Task CreateSwaggerClientAsync() { - var swaggerClient = (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: "SwaggerClient")) + var swaggerClient = + (await _keycloakClient.GetClientsAsync(_keycloakOptions.RealmName, clientId: "SwaggerClient")) .FirstOrDefault(); - + if (swaggerClient == null) { var webGatewaySwaggerRootUrl = _configuration[$"Clients:WebGateway:RootUrl"].TrimEnd('/'); @@ -155,7 +188,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency var orderingServiceRootUrl = _configuration[$"Clients:OrderingService:RootUrl"].TrimEnd('/'); var paymentServiceRootUrl = _configuration[$"Clients:PaymentService:RootUrl"].TrimEnd('/'); var cmskitServiceRootUrl = _configuration[$"Clients:CmskitService:RootUrl"].TrimEnd('/'); - + swaggerClient = new Client { ClientId = "SwaggerClient", @@ -197,13 +230,14 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency Name = "Public Web Application", Protocol = "openid-connect", Enabled = true, - BaseUrl = publicWebRootUrl, + BaseUrl = publicWebRootUrl, RedirectUris = new List { $"{publicWebRootUrl.TrimEnd('/')}/signin-oidc" }, FrontChannelLogout = true, - PublicClient = true + PublicClient = true, + ImplicitFlowEnabled = true // for hybrid flow }; publicWebClient.Attributes = new Dictionary { @@ -211,7 +245,7 @@ public class KeyCloakDataSeeder : IDataSeedContributor, ITransientDependency }; await _keycloakClient.CreateClientAsync(_keycloakOptions.RealmName, publicWebClient); - + await AddOptionalClientScopesAsync( "PublicWeb", new List From bd7290f6377e66d018bd62fe865ca4c84c2474d8 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 26 Oct 2022 03:58:02 -0400 Subject: [PATCH 25/32] updated angular scopes --- apps/angular/src/environments/environment.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/angular/src/environments/environment.ts b/apps/angular/src/environments/environment.ts index 243cea14..61d849c6 100644 --- a/apps/angular/src/environments/environment.ts +++ b/apps/angular/src/environments/environment.ts @@ -13,8 +13,7 @@ export const environment = { redirectUri: baseUrl, clientId: 'Web', responseType: 'code', - scope: 'offline_access openid profile email phone', - // scope: 'offline_access openid profile email phone AccountService IdentityService AdministrationService CatalogService OrderingService', //TODO: Update when https://github.com/AnderssonPeter/Keycloak.Net/pull/5 is merged + scope: 'offline_access openid profile email phone roles AdministrationService IdentityService BasketService CatalogService OrderingService PaymentService CmskitService', //requireHttps: true, }, apis: { From 6418623dcf354e3e3fb464a38018ba59cb1cd1f6 Mon Sep 17 00:00:00 2001 From: malik masis Date: Thu, 27 Oct 2022 09:37:53 +0300 Subject: [PATCH 26/32] Update tye.yaml --- tye.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tye.yaml b/tye.yaml index 73ac37d4..de0f4014 100644 --- a/tye.yaml +++ b/tye.yaml @@ -94,14 +94,14 @@ services: - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 -# - name: public-web -# project: apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj -# bindings: -# - protocol: https -# port: 44335 -# env: -# - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx -# - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 +- name: public-web + project: apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj + bindings: + - protocol: https + port: 44335 + env: + - Kestrel__Certificates__Default__Path=../../../../etc/dev-cert/localhost.pfx + - Kestrel__Certificates__Default__Password=8b6039b6-c67a-448b-977b-0ce6d3fcfd49 - name: keycloak-seeder project: shared/EShopOnAbp.Keycloak.DbMigrator/EShopOnAbp.Keycloak.DbMigrator.csproj \ No newline at end of file From e92d460cdaeb2803f2e2ace657a0c7e0b27ae0ed Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 29 Oct 2022 03:08:07 -0400 Subject: [PATCH 27/32] removed unused keycloak settings --- apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json index c339e14c..dd89b1f3 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/appsettings.json @@ -42,13 +42,6 @@ "IsOnProd": "false", "MetaAddress": "http://localhost:8080/realms/master/.well-known/openid-configuration" }, - "Keycloak": { - "ServerRealm": "http://localhost:8080/realms/master", - "Metadata": "http://localhost:8080/realms/master/.well-known/openid-configuration", - "ClientId": "PublicWeb", - "TokenExchange": "http://localhost:8080/realms/master/protocol/openid-connect/token", - "Audience": "some-audience" - }, "ReverseProxy": { "Routes": { "route1" : { From 5cfad0df8ea303f972cb00443af0776dfb7cf764 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 29 Oct 2022 03:10:27 -0400 Subject: [PATCH 28/32] Added UserLoggedInEto event publish for user sync --- .../EShopOnAbpPublicWebModule.cs | 120 +++++++++++++----- .../EShopOnAbp.PublicWeb/UserLoggedInEto.cs | 16 +++ 2 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index b0078b9b..12440571 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -22,8 +22,14 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Polly; using StackExchange.Redis; using System; +using System.Collections.Generic; +using System.Linq; using System.Net.Http.Headers; +using System.Security.Claims; using Microsoft.AspNetCore.Authentication.OAuth.Claims; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Volo.Abp; using Volo.Abp.Account; using Volo.Abp.AspNetCore.Authentication.OpenIdConnect; @@ -38,6 +44,7 @@ using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.AutoMapper; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.RabbitMq; using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.IdentityModel.Web; @@ -167,12 +174,23 @@ public class EShopOnAbpPublicWebModule : AbpModule // options.NonceCookie.SameSite = SameSiteMode.Unspecified; // options.CorrelationCookie.SameSite = SameSiteMode.Unspecified; // - // options.TokenValidationParameters = new TokenValidationParameters - // { - // NameClaimType = "name", - // RoleClaimType = ClaimTypes.Role, - // ValidateIssuer = true - // }; + options.TokenValidationParameters = new TokenValidationParameters + { + NameClaimType = "name", + RoleClaimType = ClaimTypes.Role, + ValidateIssuer = true + }; + + options.Events.OnAuthorizationCodeReceived = async (authContext) => + { + var userLoggedInEto = CreateUserLoggedInEto(authContext.Principal, authContext.HttpContext); + if (userLoggedInEto != null) + { + var eventBus = + authContext.HttpContext.RequestServices.GetRequiredService(); + await eventBus.PublishAsync(userLoggedInEto); + } + }; if (AbpClaimTypes.UserName != "preferred_username") { @@ -181,6 +199,7 @@ public class EShopOnAbpPublicWebModule : AbpModule options.ClaimActions.RemoveDuplicate(AbpClaimTypes.UserName); } }); + if (Convert.ToBoolean(configuration["AuthServer:IsOnProd"])) { context.Services.Configure("oidc", options => @@ -248,33 +267,6 @@ public class EShopOnAbpPublicWebModule : AbpModule }); } - private void ConfigureBasketHttpClient(ServiceConfigurationContext context) - { - context.Services.AddStaticHttpClientProxies( - typeof(BasketServiceContractsModule).Assembly, - remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName - ); - - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - } - - private void ConfigurePayment(IConfiguration configuration) - { - Configure(options => - { - options.PaymentSuccessfulCallbackUrl = - configuration["App:SelfUrl"].EnsureEndsWith('/') + "PaymentCompleted"; - }); - - Configure(options => - { - options.ConfigureIcon(PaymentMethodNames.PayPal, "fa-cc-paypal paypal"); - }); - } - public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); @@ -317,4 +309,66 @@ public class EShopOnAbpPublicWebModule : AbpModule // endpoints.MapMetrics(); }); } + + private void ConfigureBasketHttpClient(ServiceConfigurationContext context) + { + context.Services.AddStaticHttpClientProxies( + typeof(BasketServiceContractsModule).Assembly, + remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } + + private void ConfigurePayment(IConfiguration configuration) + { + Configure(options => + { + options.PaymentSuccessfulCallbackUrl = + configuration["App:SelfUrl"].EnsureEndsWith('/') + "PaymentCompleted"; + }); + + Configure(options => + { + options.ConfigureIcon(PaymentMethodNames.PayPal, "fa-cc-paypal paypal"); + }); + } + + private UserLoggedInEto CreateUserLoggedInEto(ClaimsPrincipal principal, HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + + if (principal == null) + { + logger.LogWarning($"AuthorizationCode does not contain principal to create/update user!"); + return null; + } + + var claims = principal.Claims.ToList(); + + var userNameClaim = claims.FirstOrDefault(x => x.Type == "preferred_username"); + var emailClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.Email); + var isEmailVerified = claims.FirstOrDefault(x => x.Type == "email_verified")?.Value == "true"; + var phoneNumberClaim = claims.FirstOrDefault(x => x.Type == "phone"); + var userIdString = claims.First(t => t.Type == ClaimTypes.NameIdentifier).Value; + + if (!Guid.TryParse(userIdString, out Guid userId)) + { + logger.LogWarning( + $"Handling UserLoggedInEvent... User creation failed! {userIdString} can not be parsed!"); + return null; + } + + return new UserLoggedInEto + { + Id = userId, + Email = emailClaim?.Value, + UserName = userNameClaim?.Value, + Phone = phoneNumberClaim?.Value, + IsEmailVerified = isEmailVerified + }; + } } \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs new file mode 100644 index 00000000..f7ffa497 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus; + +namespace EShopOnAbp.PublicWeb; + +[EventName("EShopOnAbp.Identity.UserLoggedIn")] +[Serializable] +public class UserLoggedInEto : EtoBase +{ + public Guid Id { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + public string UserName { get; set; } + public bool IsEmailVerified { get; set; } +} \ No newline at end of file From 3c0b63380beff994c798571f570ef6cc0fcef72c Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 29 Oct 2022 03:11:03 -0400 Subject: [PATCH 29/32] added handler for user sync --- .../ETOs/UserLoggedInEto.cs | 17 ++++ .../UserLoggedInEventHandler.cs | 98 +++++++++++++++++++ .../IdentityServiceHttpApiHostModule.cs | 8 +- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 services/identity/src/EShopOnAbp.IdentityService.Application.Contracts/ETOs/UserLoggedInEto.cs create mode 100644 services/identity/src/EShopOnAbp.IdentityService.Application/UserLoggedInEventHandler.cs diff --git a/services/identity/src/EShopOnAbp.IdentityService.Application.Contracts/ETOs/UserLoggedInEto.cs b/services/identity/src/EShopOnAbp.IdentityService.Application.Contracts/ETOs/UserLoggedInEto.cs new file mode 100644 index 00000000..d163d5f4 --- /dev/null +++ b/services/identity/src/EShopOnAbp.IdentityService.Application.Contracts/ETOs/UserLoggedInEto.cs @@ -0,0 +1,17 @@ +using System; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus; + +namespace EShopOnAbp.IdentityService.ETOs +{ + [EventName("EShopOnAbp.Identity.UserLoggedIn")] + [Serializable] + public class UserLoggedInEto : EtoBase + { + public Guid Id { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + public string UserName { get; set; } + public bool IsEmailVerified { get; set; } + } +} \ No newline at end of file diff --git a/services/identity/src/EShopOnAbp.IdentityService.Application/UserLoggedInEventHandler.cs b/services/identity/src/EShopOnAbp.IdentityService.Application/UserLoggedInEventHandler.cs new file mode 100644 index 00000000..058db2d8 --- /dev/null +++ b/services/identity/src/EShopOnAbp.IdentityService.Application/UserLoggedInEventHandler.cs @@ -0,0 +1,98 @@ +using System.Threading.Tasks; +using EShopOnAbp.IdentityService.ETOs; +using Microsoft.Extensions.Logging; +using Volo.Abp; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Identity; +using Volo.Abp.Uow; + +namespace EShopOnAbp.IdentityService; + +public class UserLoggedInEventHandler : IDistributedEventHandler, ITransientDependency +{ + private readonly IdentityUserManager _userManager; + private readonly ILogger _logger; + + public UserLoggedInEventHandler(IdentityUserManager userManager, ILogger logger) + { + _userManager = userManager; + _logger = logger; + } + + + [UnitOfWork] + public async virtual Task HandleEventAsync(UserLoggedInEto eventData) + { + if (eventData == null) + { + _logger.LogWarning($"Handling UserLoggedInEvent failed! No user information found!"); + return; + } + + var user = await _userManager.FindByIdAsync(eventData.Id.ToString()); + + if (user == null) + { + await CreateCurrentUserAsync(eventData); + } + else + { + await UpdateCurrentUserAsync(user, eventData); + } + } + + protected virtual async Task CreateCurrentUserAsync(UserLoggedInEto userInfo) + { + var user = new IdentityUser( + userInfo.Id, + userInfo.UserName, + userInfo.Email); + + user.SetEmailConfirmed(userInfo.IsEmailVerified); + + if (!string.IsNullOrEmpty(userInfo.Phone)) + { + user.SetPhoneNumber(userInfo.Phone, false); + } + + // This should run once to sync the admin userIds that seeded by IdentityModule and the Keycloak admin + if (userInfo.UserName == "admin") + { + var adminUser = await _userManager.FindByNameAsync("admin"); + await _userManager.DeleteAsync(adminUser); + } + + var result = await _userManager.CreateAsync(user); + + if (!result.Succeeded) + { + throw new AbpException(string.Join('\n', result.Errors)); + } + + _logger.LogInformation($"Handling UserLoggedInEvent... Created new user with Id:{userInfo.Id}"); + } + + protected virtual async Task UpdateCurrentUserAsync(IdentityUser user, UserLoggedInEto userInfo) + { + if (user.Email != userInfo.Email) + { + _logger.LogInformation($"Handling UserLoggedInEvent... Updating the user email with:{userInfo.Email}"); + await _userManager.SetEmailAsync(user, userInfo.Email); + } + + if (user.PhoneNumber != userInfo.Phone) + { + _logger.LogInformation( + $"Handling UserLoggedInEvent... Updating the user phone with:{userInfo.Phone}"); + await _userManager.SetPhoneNumberAsync(user, userInfo.Phone); + } + + if (user.UserName != userInfo.UserName) + { + _logger.LogInformation( + $"Handling UserLoggedInEvent... Updating the user name with:{userInfo.UserName}"); + await _userManager.SetUserNameAsync(user, userInfo.UserName); + } + } +} \ No newline at end of file diff --git a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs index 1d837bb5..c979c499 100644 --- a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs +++ b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Volo.Abp; using Volo.Abp.Modularity; @@ -43,7 +44,6 @@ public class IdentityServiceHttpApiHostModule : AbpModule apiTitle: "IdentityService API" ); - context.Services.AddCors(options => { options.AddDefaultPolicy(builder => @@ -62,6 +62,12 @@ public class IdentityServiceHttpApiHostModule : AbpModule .AllowCredentials(); }); }); + + // Keycloak handles the user creation that a user name can be multiple words + Configure(options => + { + options.User.AllowedUserNameCharacters = null; + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) From 0ec4760656fbb885a4196a5191c8ca09d33b223c Mon Sep 17 00:00:00 2001 From: malik masis Date: Mon, 31 Oct 2022 17:32:16 +0300 Subject: [PATCH 30/32] Removed domain dependency from web-public --- .../src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj | 1 - .../src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj index 37fe3838..0e9f9fdc 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj @@ -8,7 +8,6 @@ - diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index b0078b9b..2fdff99b 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -70,7 +70,6 @@ namespace EShopOnAbp.PublicWeb; typeof(PaymentServiceHttpApiClientModule), typeof(AbpAutoMapperModule), typeof(CmskitServiceHttpApiClientModule), - typeof(CmsKitDomainModule), typeof(CmsKitPublicWebModule) )] public class EShopOnAbpPublicWebModule : AbpModule From 00570116a2dfba07a9d37ef29c2410ff9446246c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 22 Nov 2022 11:13:49 +0300 Subject: [PATCH 31/32] Fix OrderAppService.GetMyOrdersAsync --- .../Orders/OrderAppService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs index 93bcc00c..0ac0dfd8 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs @@ -40,6 +40,11 @@ public class OrderAppService : ApplicationService, IOrderAppService [AllowAnonymous] public async Task> GetMyOrdersAsync(GetMyOrdersInput input) { + if (CurrentUser.Id == null) + { + return new List(); + } + ISpecification specification = SpecificationFactory.Create(input.Filter); var orders = await _orderRepository.GetOrdersByUserId(CurrentUser.GetId(), specification, true); return CreateOrderDtoMapping(orders); From 991fefe67caa560517e76efdb9b626fef098e6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 22 Nov 2022 11:14:05 +0300 Subject: [PATCH 32/32] Update old AuthServer settings. --- .../web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json | 2 +- gateways/web/src/EShopOnAbp.WebGateway/appsettings.json | 2 +- .../appsettings.json | 2 +- .../src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json index 119795be..c36665c8 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json @@ -4,7 +4,7 @@ "CorsOrigins": "https://localhost:44335" }, "AuthServer": { - "Authority": "https://localhost:44330", + "Authority": "http://localhost:8080/realms/master", "RequireHttpsMetadata": "true", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" diff --git a/gateways/web/src/EShopOnAbp.WebGateway/appsettings.json b/gateways/web/src/EShopOnAbp.WebGateway/appsettings.json index dea2bd3b..f9543eef 100644 --- a/gateways/web/src/EShopOnAbp.WebGateway/appsettings.json +++ b/gateways/web/src/EShopOnAbp.WebGateway/appsettings.json @@ -4,7 +4,7 @@ "CorsOrigins": "http://localhost:4200" }, "AuthServer": { - "Authority": "https://localhost:44330", + "Authority": "http://localhost:8080/realms/master", "RequireHttpsMetadata": "true", "SwaggerClientId": "WebGateway_Swagger", "SwaggerClientSecret": "1q2w3e*" diff --git a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json index 6794a32d..a9f4e973 100644 --- a/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json +++ b/services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/appsettings.json @@ -19,7 +19,7 @@ "GrantType": "client_credentials", "ClientId": "EShopOnAbp_AdministrationService", "ClientSecret": "1q2w3e*", - "Authority": "https://localhost:44330", + "Authority": "http://localhost:8080/realms/master", "Scope": "IdentityService" } }, diff --git a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json index 750d9c24..6fefb7e9 100644 --- a/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json +++ b/services/cmskit/src/EShopOnAbp.CmskitService.HttpApi.Host/appsettings.json @@ -51,7 +51,7 @@ "GrantType": "client_credentials", "ClientId": "EShopOnAbp_CmskitService", "ClientSecret": "1q2w3e*", - "Authority": "https://localhost:44330", + "Authority": "http://localhost:8080/realms/master", "Scope": "IdentityService" } }