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