From 950c125b8757891353299e28f596f155fbc9f44c Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 22 Oct 2020 17:32:14 +0800 Subject: [PATCH] reconstitute the IdentityServer module --- .../LINGYUN.Abp.Account.Web.csproj | 2 +- ...ntityServerPermissionDefinitionProvider.cs | 46 +- .../AbpIdentityServerPermissions.cs | 59 +-- .../Dto/ApiResourceCreateOrUpdateDto.cs | 3 + .../ApiResources/Dto/ApiResourceDto.cs | 5 +- .../Clients/Dto/ClientCloneDto.cs | 5 + .../Clients/Dto/ClientUpdateDto.cs | 11 +- .../Clients/IClientAppService.cs | 7 + .../Dto/IdentityResourceDto.cs | 2 +- .../Localization/Resources/en.json | 25 +- .../Localization/Resources/zh-Hans.json | 31 +- .../AbpIdentityServerAppServiceBase.cs | 11 +- .../AbpIdentityServerAutoMapperProfile.cs | 6 +- .../ApiResources/ApiResourceAppService.cs | 120 +++-- .../Clients/ClientAppService.cs | 144 +++-- .../IdentityResourceAppService.cs | 32 +- .../ApiResources/IApiResourceRepository.cs | 11 + .../Grants/IPersistentGrantRepository.cs | 3 +- .../IIdentityResourceRepository.cs | 11 + .../EfCoreApiResourceRepository.cs | 35 ++ .../EfCoreIdentityResourceRepository.cs | 35 ++ .../AbpIdentityServerHttpApiModule.cs | 15 +- .../Clients/ClientController.cs | 21 + .../LINGYUN.ApiGateway.Host/event-bus-cap.db | Bin 32768 -> 32768 bytes ...AbpIdentityServerAdminHttpApiHostModule.cs | 10 +- vueJs/src/api/api-resources.ts | 2 + vueJs/src/api/clients.ts | 74 ++- vueJs/src/api/identity-server4.ts | 36 ++ vueJs/src/api/types.ts | 9 +- vueJs/src/lang/en.ts | 142 ----- vueJs/src/lang/zh.ts | 142 ----- vueJs/src/router/modules/identityServer.ts | 8 +- .../ApiResourceCreateOrEditForm.vue | 141 +++-- .../components/ApiResourceScopeEditForm.vue | 56 +- .../components/ApiResourceSecretEditForm.vue | 250 --------- .../identityServer/api-resources/index.vue | 8 +- .../client/components/ClientClaimEditForm.vue | 236 ++++----- .../client/components/ClientCloneForm.vue | 86 +-- .../client/components/ClientCreateForm.vue | 210 ++++---- .../client/components/ClientEditForm.vue | 501 +++++++++++++----- .../components/ClientPermissionEditForm.vue | 147 ----- .../components/ClientPropertyEditForm.vue | 199 ------- .../components/ClientSecretEditForm.vue | 305 ----------- .../admin/identityServer/client/index.vue | 94 ++-- .../components/PropertiesEditForm.vue | 169 ++++++ .../identityServer/components/ScopeInput.vue | 190 ------- .../components/SecretEditForm.vue | 257 +++++++++ .../IdentityResourceCreateOrEditForm.vue | 62 ++- .../identity-resources/index.vue | 12 +- 49 files changed, 1827 insertions(+), 2159 deletions(-) create mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs create mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs create mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/ApiResources/EfCoreApiResourceRepository.cs create mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/IdentityResources/EfCoreIdentityResourceRepository.cs create mode 100644 vueJs/src/api/identity-server4.ts delete mode 100644 vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceSecretEditForm.vue delete mode 100644 vueJs/src/views/admin/identityServer/client/components/ClientPermissionEditForm.vue delete mode 100644 vueJs/src/views/admin/identityServer/client/components/ClientPropertyEditForm.vue delete mode 100644 vueJs/src/views/admin/identityServer/client/components/ClientSecretEditForm.vue create mode 100644 vueJs/src/views/admin/identityServer/components/PropertiesEditForm.vue delete mode 100644 vueJs/src/views/admin/identityServer/components/ScopeInput.vue create mode 100644 vueJs/src/views/admin/identityServer/components/SecretEditForm.vue diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj index 78a167373..5ec9bd15e 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj @@ -1,6 +1,6 @@  - + netcoreapp3.1 diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissionDefinitionProvider.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissionDefinitionProvider.cs index 6b19a03e1..8466f840c 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissionDefinitionProvider.cs @@ -28,57 +28,29 @@ namespace LINGYUN.Abp.IdentityServer clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Create, L("Permissions:Create"), MultiTenancySides.Host); clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Update, L("Permissions:Update"), MultiTenancySides.Host); clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Clone, L("Permissions:Clone"), MultiTenancySides.Host); - clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Enabled, L("Permissions:Enabled"), MultiTenancySides.Host); - clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Disabled, L("Permissions:Disabled"), MultiTenancySides.Host); clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Delete, L("Permissions:Delete"), MultiTenancySides.Host); clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.ManagePermissions, L("Permissions:ManagePermissions"), MultiTenancySides.Host); - - // 客户端声明权限 - var clientClaimPermissiosn = clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Claims.Default, L("Permissions:Clients:Claims"), MultiTenancySides.Host); - clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Create, L("Permissions:Create"), MultiTenancySides.Host); - clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Update, L("Permissions:Update"), MultiTenancySides.Host); - clientClaimPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Claims.Delete, L("Permissions:Delete"), MultiTenancySides.Host); - - // 客户端密钥权限 - var clientSecretPermissiosn = clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Secrets.Default, L("Permissions:Clients:Secrets"), MultiTenancySides.Host); - clientSecretPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Secrets.Create, L("Permissions:Create"), MultiTenancySides.Host); - clientSecretPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Secrets.Update, L("Permissions:Update"), MultiTenancySides.Host); - clientSecretPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Secrets.Delete, L("Permissions:Delete"), MultiTenancySides.Host); - - // 客户端属性权限 - var clientPropertyPermissiosn = clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.Properties.Default, L("Permissions:Clients:Properties"), MultiTenancySides.Host); - clientPropertyPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Properties.Create, L("Permissions:Create"), MultiTenancySides.Host); - clientPropertyPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Properties.Update, L("Permissions:Update"), MultiTenancySides.Host); - clientPropertyPermissiosn.AddChild(AbpIdentityServerPermissions.Clients.Properties.Delete, L("Permissions:Delete"), MultiTenancySides.Host); + clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.ManageClaims, L("Permissions:ManageClaims"), MultiTenancySides.Host); + clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.ManageSecrets, L("Permissions:ManageSecrets"), MultiTenancySides.Host); + clientPermissions.AddChild(AbpIdentityServerPermissions.Clients.ManageProperties, L("Permissions:ManageProperties"), MultiTenancySides.Host); // Api资源权限 var apiResourcePermissions = identityServerGroup.AddPermission(AbpIdentityServerPermissions.ApiResources.Default, L("Permissions:ApiResources"), MultiTenancySides.Host); apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Create, L("Permissions:Create"), MultiTenancySides.Host); apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Update, L("Permissions:Update"), MultiTenancySides.Host); apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Delete, L("Permissions:Delete"), MultiTenancySides.Host); - - // Api作用域权限 - var apiResourceScopePermissions = apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Scope.Default, L("Permissions:ApiResources:Scope"), MultiTenancySides.Host); - apiResourceScopePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Scope.Create, L("Permissions:Create"), MultiTenancySides.Host); - apiResourceScopePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Scope.Update, L("Permissions:Update"), MultiTenancySides.Host); - apiResourceScopePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Scope.Delete, L("Permissions:Delete"), MultiTenancySides.Host); - - // Api密钥权限 - var apiResourceSecretPermissions = apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Secrets.Default, L("Permissions:ApiResources:Secrets"), MultiTenancySides.Host); - apiResourceSecretPermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Secrets.Create, L("Permissions:Create"), MultiTenancySides.Host); - apiResourceSecretPermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Secrets.Update, L("Permissions:Update"), MultiTenancySides.Host); - apiResourceSecretPermissions.AddChild(AbpIdentityServerPermissions.ApiResources.Secrets.Delete, L("Permissions:Delete"), MultiTenancySides.Host); + apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.ManageClaims, L("Permissions:ManageClaims"), MultiTenancySides.Host); + apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.ManageSecrets, L("Permissions:ManageSecrets"), MultiTenancySides.Host); + apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.ManageProperties, L("Permissions:ManageProperties"), MultiTenancySides.Host); + apiResourcePermissions.AddChild(AbpIdentityServerPermissions.ApiResources.ManageScopes, L("Permissions:ManageScopes"), MultiTenancySides.Host); // 身份资源权限 var identityResourcePermissions = identityServerGroup.AddPermission(AbpIdentityServerPermissions.IdentityResources.Default, L("Permissions:IdentityResources"), MultiTenancySides.Host); identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.Create, L("Permissions:Create"), MultiTenancySides.Host); identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.Update, L("Permissions:Update"), MultiTenancySides.Host); identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.Delete, L("Permissions:Delete"), MultiTenancySides.Host); - - // 身份资源属性权限 - var identityResourcePropertyPermissiosn = identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.Properties.Default, L("Permissions:IdentityResources:Properties"), MultiTenancySides.Host); - identityResourcePropertyPermissiosn.AddChild(AbpIdentityServerPermissions.IdentityResources.Properties.Create, L("Permissions:Create"), MultiTenancySides.Host); - identityResourcePropertyPermissiosn.AddChild(AbpIdentityServerPermissions.IdentityResources.Properties.Delete, L("Permissions:Delete"), MultiTenancySides.Host); + identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.ManageClaims, L("Permissions:ManageClaims"), MultiTenancySides.Host); + identityResourcePermissions.AddChild(AbpIdentityServerPermissions.IdentityResources.ManageProperties, L("Permissions:ManageProperties"), MultiTenancySides.Host); } protected virtual LocalizableString L(string name) diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissions.cs index 5dbe0c40a..8e8a5e284 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissions.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/AbpIdentityServerPermissions.cs @@ -2,7 +2,7 @@ { public class AbpIdentityServerPermissions { - public const string GroupName = "IdentityServer"; + public const string GroupName = "AbpIdentityServer"; public static class Clients { @@ -11,33 +11,10 @@ public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; public const string Clone = Default + ".Clone"; - public const string Enabled = Default + ".Enabled"; - public const string Disabled = Default + ".Disabled"; public const string ManagePermissions = Default + ".ManagePermissions"; - - public static class Claims - { - public const string Default = Clients.Default + ".Claims"; - public const string Create = Default + ".Create"; - public const string Update = Default + ".Update"; - public const string Delete = Default + ".Delete"; - } - - public static class Secrets - { - public const string Default = Clients.Default + ".Secrets"; - public const string Create = Default + ".Create"; - public const string Update = Default + ".Update"; - public const string Delete = Default + ".Delete"; - } - - public static class Properties - { - public const string Default = Clients.Default + ".Properties"; - public const string Create = Default + ".Create"; - public const string Update = Default + ".Update"; - public const string Delete = Default + ".Delete"; - } + public const string ManageClaims = Default + ".ManageClaims"; + public const string ManageSecrets = Default + ".ManageSecrets"; + public const string ManageProperties = Default + ".ManageProperties"; } public static class ApiResources @@ -46,21 +23,10 @@ public const string Create = Default + ".Create"; public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; - public static class Scope - { - public const string Default = ApiResources.Default + ".Scope"; - public const string Create = Default + ".Create"; - public const string Update = Default + ".Update"; - public const string Delete = Default + ".Delete"; - } - - public static class Secrets - { - public const string Default = ApiResources.Default + ".Secrets"; - public const string Create = Default + ".Create"; - public const string Update = Default + ".Update"; - public const string Delete = Default + ".Delete"; - } + public const string ManageScopes = Default + ".ManageScopes"; + public const string ManageClaims = Default + ".ManageClaims"; + public const string ManageSecrets = Default + ".ManageSecrets"; + public const string ManageProperties = Default + ".ManageProperties"; } public static class IdentityResources @@ -69,13 +35,8 @@ public const string Create = Default + ".Create"; public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; - - public static class Properties - { - public const string Default = IdentityResources.Default + ".Properties"; - public const string Create = Default + ".Create"; - public const string Delete = Default + ".Delete"; - } + public const string ManageClaims = Default + ".ManageClaims"; + public const string ManageProperties = Default + ".ManageProperties"; } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceCreateOrUpdateDto.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceCreateOrUpdateDto.cs index ece1a6d61..d2a98b567 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceCreateOrUpdateDto.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceCreateOrUpdateDto.cs @@ -20,11 +20,14 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources public List Secrets { get; set; } + public Dictionary Properties { get; set; } + protected ApiResourceCreateOrUpdateDto() { UserClaims = new List(); Scopes = new List(); Secrets = new List(); + Properties = new Dictionary(); } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceDto.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceDto.cs index c84052616..71d4e6335 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceDto.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/ApiResources/Dto/ApiResourceDto.cs @@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos; namespace LINGYUN.Abp.IdentityServer.ApiResources { - public class ApiResourceDto : FullAuditedEntityDto + public class ApiResourceDto : ExtensibleFullAuditedEntityDto { public string Name { get; set; } @@ -20,11 +20,14 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources public List UserClaims { get; set; } + public Dictionary Properties { get; set; } + public ApiResourceDto() { UserClaims = new List(); Scopes = new List(); Secrets = new List(); + Properties = new Dictionary(); } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs index 3ebd69948..9139018cb 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientCloneDto.cs @@ -39,6 +39,10 @@ namespace LINGYUN.Abp.IdentityServer.Clients /// public bool CopyClaim { get; set; } /// + /// 复制客户端密钥 + /// + public bool CopySecret { get; set; } + /// /// 复制客户端跨域来源 /// public bool CopyAllowedCorsOrigin { get; set; } @@ -64,6 +68,7 @@ namespace LINGYUN.Abp.IdentityServer.Clients CopyPostLogoutRedirectUri = true; CopyPropertie = true; CopyRedirectUri = true; + CopySecret = true; } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs index c8d740c42..dad7d749c 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/Dto/ClientUpdateDto.cs @@ -83,13 +83,9 @@ namespace LINGYUN.Abp.IdentityServer.Clients public int DeviceCodeLifetime { get; set; } /// - /// Api资源(AllowScopes) + /// 允许的作用域 /// - public List ApiResources { get; set; } - /// - /// 身份资源(AllowScopes) - /// - public List IdentityResources { get; set; } + public List AllowedScopes { get; set; } /// /// 允许同源 /// @@ -123,8 +119,7 @@ namespace LINGYUN.Abp.IdentityServer.Clients { Enabled = true; DeviceCodeLifetime = 300; - ApiResources = new List(); - IdentityResources = new List(); + AllowedScopes = new List(); RedirectUris = new List(); AllowedCorsOrigins = new List(); PostLogoutRedirectUris = new List(); diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/IClientAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/IClientAppService.cs index 03b4ff465..48496ee74 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/IClientAppService.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Clients/IClientAppService.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace LINGYUN.Abp.IdentityServer.Clients @@ -13,5 +14,11 @@ namespace LINGYUN.Abp.IdentityServer.Clients ClientUpdateDto> { Task CloneAsync(Guid id, ClientCloneDto input); + + Task> GetAssignableApiResourcesAsync(); + + Task> GetAssignableIdentityResourcesAsync(); + + Task> GetAllDistinctAllowedCorsOriginsAsync(); } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs index 8e64e7298..49649a370 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/IdentityResources/Dto/IdentityResourceDto.cs @@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos; namespace LINGYUN.Abp.IdentityServer.IdentityResources { - public class IdentityResourceDto : FullAuditedEntityDto + public class IdentityResourceDto : ExtensibleFullAuditedEntityDto { public string Name { get; set; } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json index 6bd155344..5a7f49b35 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json @@ -5,19 +5,15 @@ "Permissions:Create": "Create", "Permissions:Update": "Update", "Permissions:Clone": "Clone", - "Permissions:Enabled": "Enabled", - "Permissions:Disabled": "Disabled", "Permissions:Delete": "Delete", + "Permissions:ManageClaims": "Claims", + "Permissions:ManageSecrets": "Secrets", + "Permissions:ManageScopes": "Scopes", + "Permissions:ManageProperties": "Properties", "Permissions:ManagePermissions": "Permissions", "Permissions:Clients": "Clients", - "Permissions:Clients:Claims": "Client claim", - "Permissions:Clients:Secrets": "Client secret", - "Permissions:Clients:Properties": "Client property", "Permissions:ApiResources": "ApiResources", - "Permissions:ApiResources:Scope": "Api scope", - "Permissions:ApiResources:Secrets": "Api secret", "Permissions:IdentityResources": "IdentityResources", - "Permissions:IdentityResources:Properties": "Identity property", "ClientIdExisted": "Client id: {0} already exists!", "ApiResourceNameExisted": "Api resource name: {0} already exists!", "IdentityResourceNameExisted": "Identity resource name: {0} already exists!", @@ -27,7 +23,12 @@ "ClientPropertyNotFound": "Client property: {0} not found!", "IdentityResourcePropertyNotFound": "Identity resource property: {0} not found!", "EncryptionNotImplemented": "Encryption type: {0} not implemented!", - "Information": "Info", + "Basics": "Basics", + "Authentication": "Authentication", + "Token": "Token", + "Consent": "Consent", + "DeviceFlow": "Device Flow", + "Advanced": "Advanced", "Resource:Enabled": "Enabled", "Resource:New": "Add New", "Resource:Edit": "Edit", @@ -53,6 +54,7 @@ "Secret:New": "Add New", "Secret:Type": "Type", "Secret:HashType": "Hash Type", + "Secret:HashTypeOnlySharedSecret": "The hash type applies only to the SharedSecret type", "Secret:Value": "Value", "Client:Enabled": "Enabled", "Client:New": "Add New", @@ -66,6 +68,7 @@ "Clone:CopyRedirectUri": "Copy the Client redirect Uri", "Clone:CopyAllowedScope": "Copy the Client scopes", "Clone:CopyClaim": "Copy the Client claims", + "Clone:CopySecret": "Copy the Client secrets", "Clone:CopyAllowedCorsOrigin": "Copy the Client Cors-Origin Uri", "Clone:CopyPostLogoutRedirectUri": "Copy the Client Redirect Uri", "Clone:CopyProperties": "Copy the Client Properties", @@ -110,11 +113,15 @@ "Client:UserCodeType": "User Code Type", "Claims": "Claims", "Claims:New": "Add New", + "Claims:Delete": "Delete", "Claims:Type": "Type", "Claims:Value": "Value", "Propertites": "Propertites", "Propertites:New": "Add New", + "Propertites:Key": "Key", "Propertites:Value": "Value", + "Propertites:Delete": "Delete", + "Propertites:DuplicateKey": "Property already exists and cannot add duplicates!", "Permissions": "Permissions" } } \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json index 5f948995a..6a0b008f0 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json @@ -5,19 +5,15 @@ "Permissions:Create": "新增", "Permissions:Update": "修改", "Permissions:Clone": "克隆", - "Permissions:Enabled": "启用", - "Permissions:Disabled": "停用", "Permissions:Delete": "删除", + "Permissions:ManageClaims": "管理声明", + "Permissions:ManageSecrets": "管理密钥", + "Permissions:ManageScopes": "管理作用域", + "Permissions:ManageProperties": "管理属性", "Permissions:ManagePermissions": "更改权限", "Permissions:Clients": "客户端管理", - "Permissions:Clients:Secrets": "客户端密钥", - "Permissions:Clients:Properties": "客户端属性", - "Permissions:Clients:Claims": "客户端声明", "Permissions:ApiResources": "Api资源管理", - "Permissions:ApiResources:Scope": "授权范围", - "Permissions:ApiResources:Secrets": "Api密钥", "Permissions:IdentityResources": "身份资源管理", - "Permissions:IdentityResources:Properties": "身份资源属性", "ClientIdExisted": "客户端标识: {0} 已经存在!", "ApiResourceNameExisted": "Api资源: {0} 已经存在!", "IdentityResourceNameExisted": "身份资源: {0} 已经存在!", @@ -27,7 +23,12 @@ "ClientPropertyNotFound": "客户端属性: {0} 不存在!", "IdentityResourcePropertyNotFound": "身份资源属性: {0} 不存在!", "EncryptionNotImplemented": "加密类型: {0} 未实现!", - "Information": "信息", + "Basics": "基本信息", + "Authentication": "认证/注销", + "Token": "令牌", + "Consent": "同意屏幕", + "DeviceFlow": "设备流程", + "Advanced": "高级", "Resource:Enabled": "启用资源", "Resource:New": "添加新资源", "Resource:Edit": "编辑资源", @@ -53,6 +54,7 @@ "Secret:New": "添加新密钥", "Secret:Type": "密钥类型", "Secret:HashType": "哈希类型", + "Secret:HashTypeOnlySharedSecret": "哈希类型仅适用于 SharedSecret 类型", "Secret:Value": "值", "Client:Enabled": "启用客户端", "Client:New": "添加新客户端", @@ -66,13 +68,14 @@ "Clone:CopyRedirectUri": "复制客户端重定向 Uri", "Clone:CopyAllowedScope": "复制客户端作用域", "Clone:CopyClaim": "复制客户端声明", + "Clone:CopySecret": "复制客户端密钥", "Clone:CopyAllowedCorsOrigin": "复制客户端跨域来源", "Clone:CopyPostLogoutRedirectUri": "复制客户端注销重定向 Uri", "Clone:CopyProperties": "复制客户端属性", "Clone:CopyIdentityProviderRestriction": "复制身份提供程序限制", "Client:ProtocolType": "协议类型", - "Client:RequireClientSecret": "需要客户端密钥", - "Client:RequirePkce": "需要 Pkce", + "Client:RequiredClientSecret": "需要客户端密钥", + "Client:RequiredPkce": "需要 Pkce", "Client:AllowedPlainTextPkce": "允许纯文本 Pkce", "Client:AllowedOfflineAccess": "允许离线访问", "Client:AllowedScopes": "允许的作用域", @@ -109,12 +112,16 @@ "Client:LogoUri": "徽标 Uri", "Client:UserCodeType": "用户代码类型", "Claims": "声明", - "Claims:New": "添加新声明", + "Claims:New": "添加新声明", + "Claims:Delete": "删除声明", "Claims:Type": "声明类型", "Claims:Value": "值", "Propertites": "属性", "Propertites:New": "添加新属性", + "Propertites:Key": "属性名称", "Propertites:Value": "值", + "Propertites:Delete": "删除属性", + "Propertites:DuplicateKey": "属性已经存在,不能添加重复项!", "Permissions": "权限" } } \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAppServiceBase.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAppServiceBase.cs index fecf623ad..1f4387577 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAppServiceBase.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAppServiceBase.cs @@ -1,13 +1,22 @@ -using Volo.Abp.Application.Services; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.IdentityServer.Localization; namespace LINGYUN.Abp.IdentityServer { public abstract class AbpIdentityServerAppServiceBase : ApplicationService { + private IPermissionChecker _permissionChecker; + protected IPermissionChecker PermissionChecker => LazyGetRequiredService(ref _permissionChecker); protected AbpIdentityServerAppServiceBase() { LocalizationResource = typeof(AbpIdentityServerResource); } + + protected virtual async Task IsGrantAsync(string policy) + { + return await PermissionChecker.IsGrantedAsync(policy); + } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAutoMapperProfile.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAutoMapperProfile.cs index 7a206a62d..6c2f7ae91 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAutoMapperProfile.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/AbpIdentityServerAutoMapperProfile.cs @@ -37,10 +37,12 @@ namespace LINGYUN.Abp.IdentityServer CreateMap(); CreateMap(); CreateMap() - .ForMember(dto => dto.UserClaims, map => map.MapFrom(src => src.UserClaims.Select(claim => claim.Type).ToList())); + .ForMember(dto => dto.UserClaims, map => map.MapFrom(src => src.UserClaims.Select(claim => claim.Type).ToList())) + .MapExtraProperties(); CreateMap() - .ForMember(dto => dto.UserClaims, map => map.MapFrom(src => src.UserClaims.Select(claim => claim.Type).ToList())); + .ForMember(dto => dto.UserClaims, map => map.MapFrom(src => src.UserClaims.Select(claim => claim.Type).ToList())) + .MapExtraProperties(); } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs index 7f031a1a4..c9c9e540d 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; -using Volo.Abp.IdentityServer.ApiResources; using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource; namespace LINGYUN.Abp.IdentityServer.ApiResources @@ -55,7 +54,7 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources { Enabled = input.Enabled }; - UpdateApiResourceByInput(apiResource, input); + await UpdateApiResourceByInputAsync(apiResource, input); apiResource = await ApiResourceRepository.InsertAsync(apiResource); @@ -72,7 +71,7 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources apiResource.Description = input.Description ?? apiResource.Description; apiResource.Enabled = input.Enabled; - UpdateApiResourceByInput(apiResource, input); + await UpdateApiResourceByInputAsync(apiResource, input); apiResource = await ApiResourceRepository.UpdateAsync(apiResource); @@ -90,76 +89,95 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources await CurrentUnitOfWork.SaveChangesAsync(); } - protected virtual void UpdateApiResourceByInput(ApiResource apiResource, ApiResourceCreateOrUpdateDto input) + protected virtual async Task UpdateApiResourceByInputAsync(ApiResource apiResource, ApiResourceCreateOrUpdateDto input) { - // 删除不存在的UserClaim - apiResource.UserClaims.RemoveAll(claim => !input.UserClaims.Contains(claim.Type)); - foreach (var inputClaim in input.UserClaims) + if (await IsGrantAsync(AbpIdentityServerPermissions.ApiResources.ManageClaims)) { - var userClaim = apiResource.FindClaim(inputClaim); - if (userClaim == null) + // 删除不存在的UserClaim + apiResource.UserClaims.RemoveAll(claim => !input.UserClaims.Contains(claim.Type)); + foreach (var inputClaim in input.UserClaims) { - apiResource.AddUserClaim(inputClaim); + var userClaim = apiResource.FindClaim(inputClaim); + if (userClaim == null) + { + apiResource.AddUserClaim(inputClaim); + } } } - // 删除不存在的Scope - apiResource.Scopes.RemoveAll(scope => !input.Scopes.Any(inputScope => scope.Name == inputScope.Name)); - foreach (var inputScope in input.Scopes) + if (await IsGrantAsync(AbpIdentityServerPermissions.ApiResources.ManageScopes)) { - var scope = apiResource.FindScope(inputScope.Name); - if (scope == null) + // 删除不存在的Scope + apiResource.Scopes.RemoveAll(scope => !input.Scopes.Any(inputScope => scope.Name == inputScope.Name)); + foreach (var inputScope in input.Scopes) { - scope = apiResource.AddScope( - inputScope.Name, inputScope.DisplayName, inputScope.Description, - inputScope.Required, inputScope.Emphasize, inputScope.ShowInDiscoveryDocument); - } - else - { - scope.Required = inputScope.Required; - scope.Emphasize = inputScope.Emphasize; - scope.Description = inputScope.Description; - scope.DisplayName = inputScope.DisplayName; - scope.ShowInDiscoveryDocument = inputScope.ShowInDiscoveryDocument; - // 删除不存在的ScopeUserClaim - scope.UserClaims.RemoveAll(claim => !inputScope.UserClaims.Contains(claim.Type)); - } + var scope = apiResource.FindScope(inputScope.Name); + if (scope == null) + { + scope = apiResource.AddScope( + inputScope.Name, inputScope.DisplayName, inputScope.Description, + inputScope.Required, inputScope.Emphasize, inputScope.ShowInDiscoveryDocument); + } + else + { + scope.Required = inputScope.Required; + scope.Emphasize = inputScope.Emphasize; + scope.Description = inputScope.Description; + scope.DisplayName = inputScope.DisplayName; + scope.ShowInDiscoveryDocument = inputScope.ShowInDiscoveryDocument; + // 删除不存在的ScopeUserClaim + scope.UserClaims.RemoveAll(claim => !inputScope.UserClaims.Contains(claim.Type)); + } - foreach (var inputScopeClaim in inputScope.UserClaims) - { - var scopeUserClaim = scope.FindClaim(inputScopeClaim); - if (scopeUserClaim == null) + foreach (var inputScopeClaim in inputScope.UserClaims) { - scope.AddUserClaim(inputScopeClaim); + var scopeUserClaim = scope.FindClaim(inputScopeClaim); + if (scopeUserClaim == null) + { + scope.AddUserClaim(inputScopeClaim); + } } } } - // 删除不存在的Secret - apiResource.Secrets.RemoveAll(secret => !input.Secrets.Any(inputSecret => secret.Type == inputSecret.Type && secret.Value == inputSecret.Value)); - foreach (var inputSecret in input.Secrets) + if (await IsGrantAsync(AbpIdentityServerPermissions.ApiResources.ManageSecrets)) { - // 第一次重复校验已经加密过的字符串 - if (apiResource.FindSecret(inputSecret.Value, inputSecret.Type) == null) + // 删除不存在的Secret + apiResource.Secrets.RemoveAll(secret => !input.Secrets.Any(inputSecret => secret.Type == inputSecret.Type && secret.Value == inputSecret.Value)); + foreach (var inputSecret in input.Secrets) { - var apiSecretValue = inputSecret.Value; - if (IdentityServerConstants.SecretTypes.SharedSecret.Equals(inputSecret.Type)) + // 第一次重复校验已经加密过的字符串 + if (apiResource.FindSecret(inputSecret.Value, inputSecret.Type) == null) { - if (inputSecret.HashType == HashType.Sha256) + var apiSecretValue = inputSecret.Value; + if (IdentityServerConstants.SecretTypes.SharedSecret.Equals(inputSecret.Type)) { - apiSecretValue = inputSecret.Value.Sha256(); + if (inputSecret.HashType == HashType.Sha256) + { + apiSecretValue = inputSecret.Value.Sha256(); + } + else if (inputSecret.HashType == HashType.Sha512) + { + apiSecretValue = inputSecret.Value.Sha512(); + } } - else if (inputSecret.HashType == HashType.Sha512) + // 加密之后还需要做一次校验 避免出现重复值 + var secret = apiResource.FindSecret(apiSecretValue, inputSecret.Type); + if (secret == null) { - apiSecretValue = inputSecret.Value.Sha512(); + apiResource.AddSecret(apiSecretValue, inputSecret.Expiration, inputSecret.Type, inputSecret.Description); } } - // 加密之后还需要做一次校验 避免出现重复值 - var secret = apiResource.FindSecret(apiSecretValue, inputSecret.Type); - if (secret == null) - { - apiResource.AddSecret(apiSecretValue, inputSecret.Expiration, inputSecret.Type, inputSecret.Description); - } + } + } + + if (await IsGrantAsync(AbpIdentityServerPermissions.ApiResources.ManageProperties)) + { + // 删除不存在的属性 + apiResource.Properties.RemoveAll(scope => !input.Properties.ContainsKey(scope.Key)); + foreach (var property in input.Properties) + { + apiResource.Properties[property.Key] = property.Value; } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs index 057711c51..cdb6571f1 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs @@ -1,4 +1,6 @@ -using IdentityServer4; +using LINGYUN.Abp.IdentityServer.ApiResources; +using LINGYUN.Abp.IdentityServer.IdentityResources; +using IdentityServer4; using IdentityServer4.Models; using Microsoft.AspNetCore.Authorization; using System; @@ -16,10 +18,17 @@ namespace LINGYUN.Abp.IdentityServer.Clients public class ClientAppService : AbpIdentityServerAppServiceBase, IClientAppService { protected IClientRepository ClientRepository { get; } + protected IApiResourceRepository ApiResourceRepository { get; } + protected IIdentityResourceRepository IdentityResourceRepository { get; } - public ClientAppService(IClientRepository clientRepository) + public ClientAppService( + IClientRepository clientRepository, + IApiResourceRepository apiResourceRepository, + IIdentityResourceRepository identityResourceRepository) { ClientRepository = clientRepository; + ApiResourceRepository = apiResourceRepository; + IdentityResourceRepository = identityResourceRepository; } [Authorize(AbpIdentityServerPermissions.Clients.Create)] @@ -155,22 +164,12 @@ namespace LINGYUN.Abp.IdentityServer.Clients #region AllowScope // 删除未在身份资源和Api资源中的作用域 - client.AllowedScopes.RemoveAll(scope => - !input.IdentityResources.Contains(scope.Scope) && - !input.ApiResources.Contains(scope.Scope)); - - foreach (var apiResource in input.ApiResources) - { - if (client.FindScope(apiResource) == null) - { - client.AddScope(apiResource); - } - } - foreach (var identityResource in input.IdentityResources) + client.AllowedScopes.RemoveAll(scope => !input.AllowedScopes.Contains(scope.Scope)); + foreach (var scope in input.AllowedScopes) { - if (client.FindScope(identityResource) == null) + if (client.FindScope(scope) == null) { - client.AddScope(identityResource); + client.AddScope(scope); } } @@ -245,34 +244,41 @@ namespace LINGYUN.Abp.IdentityServer.Clients #region Secrets - // 移除已经不存在的客户端密钥 - client.ClientSecrets.RemoveAll(secret => !input.Secrets.Any(inputSecret => secret.Value == inputSecret.Value && secret.Type == inputSecret.Type)); - var currentSecrets = new List(); - foreach (var inputSecret in input.Secrets) + if (await IsGrantAsync(AbpIdentityServerPermissions.Clients.ManageSecrets)) { - var inputSecretValue = inputSecret.Value; - // 如果是 SharedSecret 类型的密钥 - // 采用 IdentityServer4 服务器扩展方法加密 - if (IdentityServerConstants.SecretTypes.SharedSecret.Equals(inputSecret.Type)) + // 移除已经不存在的客户端密钥 + client.ClientSecrets.RemoveAll(secret => !input.Secrets.Any(inputSecret => secret.Value == inputSecret.Value && secret.Type == inputSecret.Type)); + foreach (var inputSecret in input.Secrets) { - if (inputSecret.HashType == HashType.Sha256) + // 先对加密过的进行过滤 + if (client.FindSecret(inputSecret.Value, inputSecret.Type) != null) { - inputSecretValue = inputSecret.Value.Sha256(); + continue; } - else if (inputSecret.HashType == HashType.Sha512) + var inputSecretValue = inputSecret.Value; + // 如果是 SharedSecret 类型的密钥 + // 采用 IdentityServer4 服务器扩展方法加密 + if (IdentityServerConstants.SecretTypes.SharedSecret.Equals(inputSecret.Type)) { - inputSecretValue = inputSecret.Value.Sha512(); + if (inputSecret.HashType == HashType.Sha256) + { + inputSecretValue = inputSecret.Value.Sha256(); + } + else if (inputSecret.HashType == HashType.Sha512) + { + inputSecretValue = inputSecret.Value.Sha512(); + } + } + else + { + throw new UserFriendlyException(L["EncryptionNotImplemented", inputSecret.Type]); } - } - else - { - throw new UserFriendlyException(L["EncryptionNotImplemented", inputSecret.Type]); - } - var clientSecret = client.FindSecret(inputSecretValue, inputSecret.Type); - if (clientSecret == null) - { - client.AddSecret(inputSecretValue, inputSecret.Expiration, inputSecret.Type, inputSecret.Description); + var clientSecret = client.FindSecret(inputSecretValue, inputSecret.Type); + if (clientSecret == null) + { + client.AddSecret(inputSecretValue, inputSecret.Expiration, inputSecret.Type, inputSecret.Description); + } } } @@ -280,27 +286,34 @@ namespace LINGYUN.Abp.IdentityServer.Clients #region Properties - // 移除不存在的属性 - client.Properties.RemoveAll(prop => input.Properties.Any(inputProp => inputProp.Key == prop.Key && inputProp.Value == prop.Value)); - foreach (var inputProp in input.Properties) + if (await IsGrantAsync(AbpIdentityServerPermissions.Clients.ManageProperties)) { - if (client.FindProperty(inputProp.Key, inputProp.Value) == null) + // 移除不存在的属性 + client.Properties.RemoveAll(prop => !input.Properties.ContainsKey(prop.Key)); + foreach (var inputProp in input.Properties) { - client.AddProperty(inputProp.Key, inputProp.Value); + if (client.FindProperty(inputProp.Key, inputProp.Value) == null) + { + client.AddProperty(inputProp.Key, inputProp.Value); + } } } + #endregion #region Claims - // 移除已经不存在的客户端声明 - client.ClientSecrets.RemoveAll(secret => !input.Claims.Any(inputClaim => secret.Value == inputClaim.Value && secret.Type == inputClaim.Type)); - foreach (var inputClaim in input.Claims) + if (await IsGrantAsync(AbpIdentityServerPermissions.Clients.ManageClaims)) { - if (client.FindClaim(inputClaim.Value, inputClaim.Type) == null) + // 移除已经不存在的客户端声明 + client.Claims.RemoveAll(secret => !input.Claims.Any(inputClaim => secret.Value == inputClaim.Value && secret.Type == inputClaim.Type)); + foreach (var inputClaim in input.Claims) { - client.AddClaim(inputClaim.Value, inputClaim.Type); + if (client.FindClaim(inputClaim.Value, inputClaim.Type) == null) + { + client.AddClaim(inputClaim.Value, inputClaim.Type); + } } } @@ -404,6 +417,13 @@ namespace LINGYUN.Abp.IdentityServer.Clients client.AddClaim(claim.Value, claim.Type); } } + if (input.CopySecret) + { + foreach (var secret in srcClient.ClientSecrets) + { + client.AddSecret(secret.Value, secret.Expiration, secret.Type, secret.Description); + } + } if (input.CopyIdentityProviderRestriction) { foreach (var provider in srcClient.IdentityProviderRestrictions) @@ -438,5 +458,35 @@ namespace LINGYUN.Abp.IdentityServer.Clients return ObjectMapper.Map(client); } + /// + /// 查询可用的Api资源 + /// + /// + public virtual async Task> GetAssignableApiResourcesAsync() + { + var resourceNames = await ApiResourceRepository.GetNamesAsync(); + + return new ListResultDto(resourceNames); + } + /// + /// 查询可用的身份资源 + /// + /// + public virtual async Task> GetAssignableIdentityResourcesAsync() + { + var resourceNames = await IdentityResourceRepository.GetNamesAsync(); + + return new ListResultDto(resourceNames); + } + /// + /// 查询所有不重复的跨域地址 + /// + /// + public virtual async Task> GetAllDistinctAllowedCorsOriginsAsync() + { + var corsOrigins = await ClientRepository.GetAllDistinctAllowedCorsOriginsAsync(); + + return new ListResultDto(corsOrigins); + } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/IdentityResources/IdentityResourceAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/IdentityResources/IdentityResourceAppService.cs index 1e42fd26d..38be28e9a 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/IdentityResources/IdentityResourceAppService.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/IdentityResources/IdentityResourceAppService.cs @@ -48,7 +48,7 @@ namespace LINGYUN.Abp.IdentityServer.IdentityResources var identityResource = new IdentityResource(GuidGenerator.Create(), input.Name, input.DisplayName, input.Description, input.Enabled, input.Required, input.Emphasize, input.ShowInDiscoveryDocument); - UpdateApiResourceByInput(identityResource, input); + await UpdateApiResourceByInputAsync(identityResource, input); await CurrentUnitOfWork.SaveChangesAsync(); @@ -61,7 +61,7 @@ namespace LINGYUN.Abp.IdentityServer.IdentityResources public virtual async Task UpdateAsync(Guid id, IdentityResourceCreateOrUpdateDto input) { var identityResource = await IdentityResourceRepository.GetAsync(id); - UpdateApiResourceByInput(identityResource, input); + await UpdateApiResourceByInputAsync(identityResource, input); identityResource = await IdentityResourceRepository.UpdateAsync(identityResource); await CurrentUnitOfWork.SaveChangesAsync(); @@ -75,7 +75,7 @@ namespace LINGYUN.Abp.IdentityServer.IdentityResources await IdentityResourceRepository.DeleteAsync(id); } - protected virtual void UpdateApiResourceByInput(IdentityResource identityResource, IdentityResourceCreateOrUpdateDto input) + protected virtual async Task UpdateApiResourceByInputAsync(IdentityResource identityResource, IdentityResourceCreateOrUpdateDto input) { if (!string.Equals(identityResource.Name, input.Name, StringComparison.InvariantCultureIgnoreCase)) { @@ -94,22 +94,28 @@ namespace LINGYUN.Abp.IdentityServer.IdentityResources identityResource.Required = input.Required; identityResource.ShowInDiscoveryDocument = input.ShowInDiscoveryDocument; - // 删除不存在的UserClaim - identityResource.UserClaims.RemoveAll(claim => input.UserClaims.Contains(claim.Type)); - foreach (var inputClaim in input.UserClaims) + if (await IsGrantAsync(AbpIdentityServerPermissions.IdentityResources.ManageClaims)) { - var userClaim = identityResource.FindUserClaim(inputClaim); - if (userClaim == null) + // 删除不存在的UserClaim + identityResource.UserClaims.RemoveAll(claim => input.UserClaims.Contains(claim.Type)); + foreach (var inputClaim in input.UserClaims) { - identityResource.AddUserClaim(inputClaim); + var userClaim = identityResource.FindUserClaim(inputClaim); + if (userClaim == null) + { + identityResource.AddUserClaim(inputClaim); + } } } - // 删除不存在的Property - identityResource.Properties.RemoveAll(scope => !input.Properties.ContainsKey(scope.Key)); - foreach (var inputProp in input.Properties) + if (await IsGrantAsync(AbpIdentityServerPermissions.IdentityResources.ManageProperties)) { - identityResource.Properties[inputProp.Key] = inputProp.Value; + // 删除不存在的Property + identityResource.Properties.RemoveAll(scope => !input.Properties.ContainsKey(scope.Key)); + foreach (var inputProp in input.Properties) + { + identityResource.Properties[inputProp.Key] = inputProp.Value; + } } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs new file mode 100644 index 000000000..e35232afd --- /dev/null +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IdentityServer.ApiResources +{ + public interface IApiResourceRepository : Volo.Abp.IdentityServer.ApiResources.IApiResourceRepository + { + Task> GetNamesAsync(CancellationToken cancellationToken = default); + } +} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/Grants/IPersistentGrantRepository.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/Grants/IPersistentGrantRepository.cs index 8bd221627..b027523c5 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/Grants/IPersistentGrantRepository.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/Grants/IPersistentGrantRepository.cs @@ -1,5 +1,4 @@ -using JetBrains.Annotations; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Volo.Abp.IdentityServer.Grants; diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs new file mode 100644 index 000000000..2b7626469 --- /dev/null +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Domain/LINGYUN/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IdentityServer.IdentityResources +{ + public interface IIdentityResourceRepository : Volo.Abp.IdentityServer.IdentityResources.IIdentityResourceRepository + { + Task> GetNamesAsync(CancellationToken cancellationToken = default); + } +} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/ApiResources/EfCoreApiResourceRepository.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/ApiResources/EfCoreApiResourceRepository.cs new file mode 100644 index 000000000..97f964b96 --- /dev/null +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/ApiResources/EfCoreApiResourceRepository.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.IdentityServer.ApiResources; +using Volo.Abp.IdentityServer.EntityFrameworkCore; + +namespace LINGYUN.Abp.IdentityServer.ApiResources +{ + [Dependency(ServiceLifetime.Transient)] + [ExposeServices( + typeof(IApiResourceRepository), + typeof(ApiResourceRepository), + typeof(Volo.Abp.IdentityServer.ApiResources.IApiResourceRepository))] + public class EfCoreApiResourceRepository : ApiResourceRepository, IApiResourceRepository + { + public EfCoreApiResourceRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task> GetNamesAsync(CancellationToken cancellationToken = default) + { + return await DbSet + .Select(x => x.Name) + .Distinct() + .ToListAsync(GetCancellationToken(cancellationToken)); + } + } +} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/IdentityResources/EfCoreIdentityResourceRepository.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/IdentityResources/EfCoreIdentityResourceRepository.cs new file mode 100644 index 000000000..ea7b5c9a7 --- /dev/null +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.EntityFrameworkCore/LINGYUN/Abp/IdentityServer/IdentityResources/EfCoreIdentityResourceRepository.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.IdentityServer.EntityFrameworkCore; +using Volo.Abp.IdentityServer.IdentityResources; + +namespace LINGYUN.Abp.IdentityServer.IdentityResources +{ + [Dependency(ServiceLifetime.Transient)] + [ExposeServices( + typeof(IIdentityResourceRepository), + typeof(IdentityResourceRepository), + typeof(Volo.Abp.IdentityServer.IdentityResources.IIdentityResourceRepository))] + public class EfCoreIdentityResourceRepository : IdentityResourceRepository, IIdentityResourceRepository + { + public EfCoreIdentityResourceRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task> GetNamesAsync(CancellationToken cancellationToken = default) + { + return await DbSet + .Select(x => x.Name) + .Distinct() + .ToListAsync(GetCancellationToken(cancellationToken)); + } + } +} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/AbpIdentityServerHttpApiModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/AbpIdentityServerHttpApiModule.cs index 2fbb3a683..377557992 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/AbpIdentityServerHttpApiModule.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/AbpIdentityServerHttpApiModule.cs @@ -1,5 +1,8 @@ -using Microsoft.Extensions.DependencyInjection; +using Localization.Resources.AbpUi; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.IdentityServer.Localization; +using Volo.Abp.Localization; using Volo.Abp.Modularity; namespace LINGYUN.Abp.IdentityServer @@ -17,5 +20,15 @@ namespace LINGYUN.Abp.IdentityServer mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpIdentityServerHttpApiModule).Assembly); }); } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + } } } diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/Clients/ClientController.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/Clients/ClientController.cs index c2254bdf4..9fd243372 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/Clients/ClientController.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN/Abp/IdentityServer/Clients/ClientController.cs @@ -57,5 +57,26 @@ namespace LINGYUN.Abp.IdentityServer.Clients { return await ClientAppService.CloneAsync(id, input); } + + [HttpGet] + [Route("assignable-api-resources")] + public virtual async Task> GetAssignableApiResourcesAsync() + { + return await ClientAppService.GetAssignableApiResourcesAsync(); + } + + [HttpGet] + [Route("assignable-identity-resources")] + public virtual async Task> GetAssignableIdentityResourcesAsync() + { + return await ClientAppService.GetAssignableIdentityResourcesAsync(); + } + + [HttpGet] + [Route("distinct-cors-origins")] + public virtual async Task> GetAllDistinctAllowedCorsOriginsAsync() + { + return await ClientAppService.GetAllDistinctAllowedCorsOriginsAsync(); + } } } diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db index 3d97c9220dc83927e506c3678837a57392931934..9b1e5086f804f4952b46769242a7c24546148687 100644 GIT binary patch literal 32768 zcmeHQ-)|d99k-ptN%N!I<|QZHNvte-ZFS9de(dbbtavzIE^Vx&NlDU!3Pj^1TgN4d zbG8#&RfVFn2TINTt)MS4}gOO1%sJN8o?slYxW5 zh5^6RvE!2t-%VMzIbr-WH8`G6ogXrOIi8>R;G~Q7d5wTZKqH_L&#y#p=dZv3iA|tLE#oH}ZEDf~(A# zrG*8R`Qp+{er49bX|cHD#qWSy8kx4ce5SHn_jc=R=5}SbRQDd%{Y;jcpZhGMMX0h(o%R6553_o%9;a<7w)$)*SbV1y2|Du(8vA$nxcGvFg?d|2l zt^D#`bAI-&c}2l?b@Zwn%ue09oKBT@H@%0oH@9I}cdxi#ulV-8Cb;k6CUfX5o*tgM zbSeD~j_PpP+wjT+TQmCibsuwA9|Om=Gi zQm0C9)KF084Ql|Ria)j=f`g3lu?jLH#=ne@2j9-P%FrK;z)1*9{5pH_n*)b)*>Uw7 zzw@P$nfzxa7k7U5^}l|YI=~Bs#hZ8UEL!=!@=b_}Un@ScW)C2=zP4Xe=Ssmjh`0C4 zrJ1ebZprhLUoX~+N4HGRRcdwX06)&ndBshL|2g+@4x-ldMsa(4y}0q!>0OBLId^w| zd;6N7uv05dmp5~64pS^KCbndf+E_4~liblI!EL$!!O2)=^+$W)LvCsPfwxf)&)1-+ zswIH)1QB!{qw9p27`uqM2%E1U;UW}XyHTlDyE*M&Q}f=0{2I5ZqLx&+gLB6r%RRZ4 zd!x9$4<0YjU|a=3&-v? zmx8=)+ZL>aN{}Kfhe{!FJS+`FRGRUr^p(${Q?~Pv>&y61$-#5Nze8>2PQ8hf{i^jY$75qDCJgCoW1T+E~0gZr0KqH_L z&57r=Ob^2L|` z_HQtZ@qui5a`D-XpFKyZ^P%zCKY}q48X58wrN#r}7k_#7DoTxo#``}^q10$-{NOQM zb}lr&`_Xfh8VQW|Uib-284d?V@U}G@8vgsTq0sPOcnpSyKV>}-8vdMPW^5pP4&Jf( zlSUJ&f>b&5M|^2}e| zk_`1ff{??wZ4)d&2rvoSNDgRkxCC|5AZhP(Uo=QUZ!8J=MGodY)kcc)2BjR%Xk3FN zNWzv4(ny%gC9>R z9VDo2LnD`rxI|q_y2K@N-0A*ti4qIc5fP?+;1Z=4hK9^O)?We;s3oM5nT%^m4mWct zSQwrRE@2S11MyZ&IH*74B(!nN#nPotCoZ*jx-VP`y#cvo${c>WzV}Sk0~v4lT6R(1 zj`C&>bTFFq|AHitu#`|U4v*rJ8vkd;9;osE12`Q1G>>U@*-wMO;nHLneM_2?(s7pEw)=u)dx4{R=X$-Rep*I!>L3W zjIteSbC}6s#1?1SH;OR|i<6r(pHXdm?jNH-qZp=i5Wv(oMyW@@ZW34oGfHtrK@yk9 zK_u4Op1Tk->TVdLe7&CJFbcu2jY|%*7fE3hvb!!(op7}C!iD8m}o&Yq}RLG>vOEMtS$uY^Ne;cR!#U$m81=DTN l2R_~S|Fk=A0bhc=Ie|$}_)>?Pas^cKlO%_o8Dc%9{{Vxp?!o{7 literal 32768 zcmeHQOKcoT86H2@NgO+q_+pk_L2IOJ5)rrS(bbR99(LAoY;PPp*pr~ZA)eTs@q~%T zJ2MW6qG+?)Awq~V2N0Y&a@f^gkdWYjSn-gMI3OW$Lqg(&w1AL6eAUkxd(s|YhG|9B z1y|C^#`S<#xrL#BO{r&G%b_KRPj9-e8=#66yI@t z!)+w|BjI;7qZ`_E_V1bTsY2$=E7>1U6{bH)I9_Eb1QY@a0fm4=6SEgCjC}oCvvjxWZkP7;8wYo*mBy~S(~%fo*jOwS7qw#H?bStXt0QkqyEv(7 zTPr(T+TBXIve(qs){ENO&DGV*a{n#2-l){}wzP+(`u1+Aevy$&+Lgttg`2DXQQE@# z>Z&Y!ZGEAzx#*p=R(jyJpMg`tLc1NlP}^&|d(ADaTH7l(-A7HYkPWw4uegmZ4K`h* zwDYRo5rv%{7iRC2nr^f5z>TiqWiCG2uhiW}0mViKwA<|+wAm~*4;r238p+n)*jTw< z*to4-TfD7Zl(1czyyT2e%wE4RlBw+NxQ`m|R&iT*r*zP)dFeYHaNnUF$yYwGMo!G0 zKR@!EMs2v^Zo8F-eiMd&j~;EoFl+D)Xpm$`wwCI(gZ)Dd-i~$p8(k#Vuv?>BqZ6~& z&L=f`*g}4rhbehKFYoO$)2Hue#>Ss#PJM3TH{;LcXY|c9yBlTO@DZ5))x^2?$LRCc z(y1x`uiGaJ3!k64`qx+gCA7>#y1KHqbo=I-Uf8cJ!7qNT^jKef2t$alHB0d+bIY|xQ-4UG$RQAy~oE;DXyt54MS+<3qfyaGZ=$9zhDK{Ky(1=TzJo~mkTJrn2rTN-# zKTQjlh{c74dN_ob!Wp_>GBrl>gy%`}XsN5w{pXTd46V@xx**H$qhE?^s+)vZl#9qO zSs@5QXWRsx+PO6PPW#AvY5vxHYWg^E$uK#!8OQj~u!rrJe1tLbwv+r)ccTZzC25Tg zui==zjl6prF2xnqITswmi*QWtGs(NCW17h0kyo0`ek(JUt!J{o$iA1YANtH@J3hm| z^Hdfn1QY@a0fm4TIv%&5NpXFS)L%>FU+MmW8C3W-;dn0+5lqE8|*HFNd* z)|Zh83iBRO%WGahVcv70(@1<4r;Pj@g`GfRdgkh<|9A(933;4X5BXbd3ITy) z5Kssx1QY@a0fm4$hqQwS&o6aoqXg@8gpA)pXY2q**;0tx|z zfI{GS!AaA`?+S8+2-~g`tsBN@DSc+3)@ISvo{XOvE7*!;)O0gwUZ& zNeGRad8tN{6lVJZqx;V#Q4FntrUQknLr)RgJy9vHsP3Qz5E>a#3BoKs20}LsP)XPk zm0Bw&JEH%CHJ7RIN}j$Aqc(vqmIKv-;d`Y(QHCZ)*+P`(sL}nWQlxJ~(cY%*SXNJ5 z>M_hVtf}r8C>-JPahz?C#bj_VrDi*qP8{Nrw-`4yTr!xA?u}R$WkXkz2(^+(qACdl zp1K%4I4%)K2a_Ns!TZl8lx-1iQQJDgB}#O{Y)+lHi)*b+baKgG%bgl7aR)Kxj9X?3 z6mB9eC90BuOI?f}AeWeq?%#m~&;YoEvY92Q6{{tM%3Fj%;l`wbSy3M+*Z)t9=H>nW zeP06*3AHH%jzvIew)KAZA1j$9jgFLN8+{(?|0&HjDRtRRNiyV;(rkkWqS9=OrBmB( z0egKa8FEQ!wt-7sG}~G$Qyn91rP=1o=yvl8-|aVnuM`JRn?fJ~f!6v= z;C;&8Ty3C|kp}NW3={zarS@1D0vBV zX|xNYkYzcDS_9xS>Zr|wV-zuT zJPkD*-Y41icIPC^7MKNrLiJ(ige*+wa$(1>lfby>5B_?RFZtb_ulAH0DsjBXz{0GK zA*`XUCyA)U@b+LJHOd_^!5JBJvd+O$nU6~X+C5Ba4Iu_3n z5xg%c9x-`Yrfmq2DVnuyErstT0hJ2q-+ZCDv``7eHwiTe-dSJ_bu~#uC5kt0z4!ru sbV}W99u$?NHMkQuOuJvNONy!Fmo2~;$6rhmQwdpACpN`WpNL8S2ISe|aR2}S diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs index 61ae931f1..eceaa69b1 100644 --- a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs @@ -55,11 +55,11 @@ namespace LINGYUN.Abp.IdentityServer4 typeof(LINGYUN.Abp.Account.AbpAccountHttpApiModule), typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerApplicationModule), typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerHttpApiModule), + typeof(LINGYUN.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule), + typeof(LINGYUN.Abp.IdentityServer.EntityFrameworkCore.AbpIdentityServerEntityFrameworkCoreModule), typeof(AbpAccountApplicationModule), typeof(AbpAccountHttpApiModule), typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(LINGYUN.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule), - typeof(AbpIdentityServerEntityFrameworkCoreModule), typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule), @@ -177,12 +177,6 @@ namespace LINGYUN.Abp.IdentityServer4 Configure(options => { var redisConfig = ConfigurationOptions.Parse(options.Configuration); - // 单独一个缓存数据库 - var databaseConfig = configuration.GetSection("Redis:DefaultDatabase"); - if (databaseConfig.Exists()) - { - redisConfig.DefaultDatabase = databaseConfig.Get(); - } options.ConfigurationOptions = redisConfig; options.InstanceName = configuration["Redis:InstanceName"]; }); diff --git a/vueJs/src/api/api-resources.ts b/vueJs/src/api/api-resources.ts index 630f58318..4a5e3966f 100644 --- a/vueJs/src/api/api-resources.ts +++ b/vueJs/src/api/api-resources.ts @@ -81,6 +81,7 @@ export class ApiResourceCreateOrUpdate { userClaims = new Array() scopes = new Array() secrets = new Array() + properties: {[key: string]: string} = {} } export class ApiResourceCreate extends ApiResourceCreateOrUpdate { @@ -98,6 +99,7 @@ export class ApiResource extends FullAuditedEntityDto { userClaims = new Array() scopes = new Array() secrets = new Array() + properties: {[key: string]: string} = {} } export class ApiResourceGetByPaged extends PagedAndSortedResultRequestDto { diff --git a/vueJs/src/api/clients.ts b/vueJs/src/api/clients.ts index c4929a346..eb901b4d7 100644 --- a/vueJs/src/api/clients.ts +++ b/vueJs/src/api/clients.ts @@ -1,5 +1,5 @@ import ApiService from './serviceBase' -import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto, SecretBase, Claim } from './types' +import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, ListResultDto, PagedResultDto, SecretBase, Claim } from './types' const sourceUrl = '/api/identity-server/clients' const serviceUrl = process.env.VUE_APP_BASE_API @@ -36,6 +36,21 @@ export default class ClientService { const _url = sourceUrl + '/' + id return ApiService.Delete(_url, serviceUrl) } + + public static getAssignableApiResources() { + const _url = sourceUrl + '/assignable-api-resources' + return ApiService.Get>(_url, serviceUrl) + } + + public static getAssignableIdentityResources() { + const _url = sourceUrl + '/assignable-identity-resources' + return ApiService.Get>(_url, serviceUrl) + } + + public static getAllDistinctAllowedCorsOrigins() { + const _url = sourceUrl + '/distinct-cors-origins' + return ApiService.Get>(_url, serviceUrl) + } } export enum HashType { @@ -53,6 +68,8 @@ export class ClientGetByPaged extends PagedAndSortedResultRequestDto { export class ClientClaim extends Claim {} +export class ClientSecret extends SecretCreateOrUpdate {} + export class ClientClone { sourceClientId = '' clientId = '' @@ -62,6 +79,7 @@ export class ClientClone { copyRedirectUri = true copyAllowedScope = true copyClaim = true + copySecret = true copyAllowedCorsOrigin = true copyPostLogoutRedirectUri = true copyPropertie = true @@ -113,14 +131,14 @@ export class Client extends FullAuditedEntityDto { userCodeType?: string deviceCodeLifetime!: number allowedScopes = new Array() - clientSecrets = new Array() + clientSecrets = new Array() allowedGrantTypes = new Array() allowedCorsOrigins = new Array() redirectUris = new Array() postLogoutRedirectUris = new Array() identityProviderRestrictions = new Array() - claims = new Array() - properties = new Array() + claims = new Array() + properties:{[key: string]: string} = {} } export class ClientCreateOrUpdate { @@ -167,8 +185,7 @@ export class ClientUpdate extends ClientCreateOrUpdate { userSsoLifetime!: number userCodeType? = '' deviceCodeLifetime = 300 - apiResources = new Array() - identityResources = new Array() + allowedScopes = new Array() allowedCorsOrigins = new Array() redirectUris = new Array() postLogoutRedirectUris = new Array() @@ -176,4 +193,49 @@ export class ClientUpdate extends ClientCreateOrUpdate { properties: {[key: string]: string} = {} secrets = new Array() claims = new Array() + + public updateByClient(client: Client) { + this.clientUri = client.clientUri + this.logoUri = client.logoUri + this.enabled = client.enabled + this.protocolType = client.protocolType + this.requireClientSecret = client.requireClientSecret + this.requireConsent = client.requireConsent + this.allowRememberConsent = client.allowRememberConsent + this.alwaysIncludeUserClaimsInIdToken = client.alwaysIncludeUserClaimsInIdToken + this.requirePkce = client.requirePkce + this.allowPlainTextPkce = client.allowPlainTextPkce + this.allowAccessTokensViaBrowser = client.allowAccessTokensViaBrowser + this.frontChannelLogoutUri = client.frontChannelLogoutUri + this.frontChannelLogoutSessionRequired = client.frontChannelLogoutSessionRequired + this.backChannelLogoutUri = client.backChannelLogoutUri + this.backChannelLogoutSessionRequired = client.backChannelLogoutSessionRequired + this.allowOfflineAccess = client.allowOfflineAccess + this.identityTokenLifetime = client.identityTokenLifetime + this.accessTokenLifetime = client.accessTokenLifetime + this.authorizationCodeLifetime = client.authorizationCodeLifetime + this.consentLifetime = client.consentLifetime + this.absoluteRefreshTokenLifetime = client.absoluteRefreshTokenLifetime + this.slidingRefreshTokenLifetime = client.slidingRefreshTokenLifetime + this.refreshTokenUsage = client.refreshTokenUsage + this.updateAccessTokenClaimsOnRefresh = client.updateAccessTokenClaimsOnRefresh + this.refreshTokenExpiration = client.refreshTokenExpiration + this.accessTokenType = client.accessTokenType + this.enableLocalLogin = client.enableLocalLogin + this.includeJwtId = client.includeJwtId + this.alwaysSendClientClaims = client.alwaysSendClientClaims + this.clientClaimsPrefix = client.clientClaimsPrefix + this.pairWiseSubjectSalt = client.pairWiseSubjectSalt + this.userSsoLifetime = client.userSsoLifetime + this.userCodeType = client.userCodeType + this.deviceCodeLifetime = client.deviceCodeLifetime + this.allowedCorsOrigins = client.allowedCorsOrigins + this.redirectUris = client.redirectUris + this.postLogoutRedirectUris = client.postLogoutRedirectUris + this.identityProviderRestrictions = client.identityProviderRestrictions + this.allowedScopes = client.allowedScopes + this.secrets = client.clientSecrets + this.claims = client.claims + this.properties = client.properties + } } diff --git a/vueJs/src/api/identity-server4.ts b/vueJs/src/api/identity-server4.ts new file mode 100644 index 000000000..c3b15daea --- /dev/null +++ b/vueJs/src/api/identity-server4.ts @@ -0,0 +1,36 @@ +import ApiService from './serviceBase' + +const openIdConfigurationUrl = '/.well-known/openid-configuration' + +export default class IdentityServer4Service { + public static getOpenIdConfiguration() { + return ApiService.Get(openIdConfigurationUrl) + } +} + +export class OpenIdConfiguration { + issuer!: string + jwks_uri!: string + authorization_endpoint!: string + token_endpoint!: string + userinfo_endpoint!: string + end_session_endpoint!: string + check_session_iframe!: string + revocation_endpoint!: string + introspection_endpoint!: string + device_authorization_endpoint!: string + frontchannel_logout_supported!: boolean + frontchannel_logout_session_supported!: boolean + backchannel_logout_supported!: boolean + backchannel_logout_session_supported!: boolean + scopes_supported = new Array() + claims_supported = new Array() + grant_types_supported = new Array() + response_types_supported = new Array() + response_modes_supported = new Array() + token_endpoint_auth_methods_supported = new Array() + id_token_signing_alg_values_supported = new Array() + subject_types_supported = new Array() + code_challenge_methods_supported = new Array() + request_parameter_supported!: boolean +} diff --git a/vueJs/src/api/types.ts b/vueJs/src/api/types.ts index b64792c14..a1e873cd4 100644 --- a/vueJs/src/api/types.ts +++ b/vueJs/src/api/types.ts @@ -259,9 +259,14 @@ export class SecretBase implements ISecret { expiration: Date | undefined } +export enum HashType { + Sha256, + Sha512 +} + export class Claim implements IClaim { - type!: string - value!: string + type = '' + value = '' constructor( type: string, diff --git a/vueJs/src/lang/en.ts b/vueJs/src/lang/en.ts index 00e8a8fa1..731253f2c 100644 --- a/vueJs/src/lang/en.ts +++ b/vueJs/src/lang/en.ts @@ -427,148 +427,6 @@ export default { aggregateJsonPath: 'Json路径', definedAggregatorProviders: '聚合提供者' }, - identityServer: { - otherOpera: '更多操作', - enabled: '启用客户端', - disbled: '停用客户端', - clientStatus: '客户端状态', - deleteClient: '删除客户端', - updateClient: '编辑客户端', - updateClientByName: '编辑客户端 {name}', - deleteClientById: '是否要删除客户端: {id}', - deleteClientSuccess: '客户端: {id} 已删除!', - createClientSuccess: '客户端: {id} 已添加!', - updateClientSuccess: '客户端: {id} 已修改!', - clientClaim: '客户端声明', - clientProperty: '客户端属性', - clientSecret: '客户端密钥', - clientPermission: '客户端权限', - deleteSecret: '删除密钥', - deleteSecretByType: '是否要删除客户端密钥: {type}', - deleteSecretSuccess: '客户端密钥: {type} 已删除!', - createSecretSuccess: '客户端密钥: {type} 已添加!', - createSecret: '添加客户端密钥', - deleteClaim: '删除声明', - deleteClaimByType: '是否要删除客户端声明: {type}', - deleteClaimSuccess: '客户端声明: {type} 已删除!', - createClaimSuccess: '客户端声明: {type} 已添加!', - createClaim: '添加客户端声明', - deleteProperty: '删除属性', - deleteClientPropertyByType: '是否要删除客户端属性: {key}', - deleteClientPropertySuccess: '客户端属性: {key} 已删除!', - createClientPropertySuccess: '客户端属性: {key} 已添加!', - createClientProperty: '添加客户端属性', - createClient: '添加客户端', - clientId: '客户端标识', - clientName: '客户端名称', - description: '客户端说明', - cloneClint: '克隆客户端', - copyAllowedGrantType: '复制客户端授权类型', - copyRedirectUri: '复制客户端重定向Uri', - copyAllowedScope: '复制客户端作用域', - copyClaim: '复制客户端声明', - copyAllowedCorsOrigin: '复制客户端跨域来源', - copyPostLogoutRedirectUri: '复制客户端注销重定向Uri', - copyPropertie: '复制客户端属性', - copyIdentityProviderRestriction: '复制身份提供程序限制', - protocolType: '协议类型', - requireClientSecret: '需要客户端密钥', - requirePkce: '需要Pkce', - allowPlainTextPkce: '允许纯文本Pkce', - allowOfflineAccess: '允许离线访问', - allowedScopes: '允许的作用域', - redirectUris: '重定向Uri', - allowedGrantTypes: '允许的授权类型', - allowAccessTokensViaBrowser: '允许通过浏览器访问令牌', - identityTokenLifetime: '身份令牌有效期(s)', - accessTokenLifetime: '访问令牌有效期(s)', - authorizationCodeLifetime: '授权码有效期(s)', - absoluteRefreshTokenLifetime: '绝对刷新令牌有效期(s)', - slidingRefreshTokenLifetime: '滚动刷新令牌有效期(s)', - deviceCodeLifetime: '设备授权码有效期(s)', - clientClaimsPrefix: '客户端声明前缀', - basicOptions: '基本设置', - frontChannelLogoutUri: '前端通道注销 Uri', - frontChannelLogoutSessionRequired: '需要前端通道注销会话', - backChannelLogoutUri: '后端通道退出 Uri', - backChannelLogoutSessionRequired: '需要后端通道注销会话', - enableLocalLogin: '启用本地登录', - postLogoutRedirectUris: '注销重定向 Uri', - identityProviderRestrictions: '身份提供程序限制', - userSsoLifetime: '用户 SSO 生命周期', - accessTokenType: '访问令牌类型', - refreshTokenUsage: '刷新令牌使用情况', - refreshTokenExpiration: '刷新令牌过期方式', - allowedCorsOrigins: '允许跨域来源', - updateAccessTokenClaimsOnRefresh: '刷新时更新访问令牌声明', - includeJwtId: '包括 Jwt 标识', - alwaysSendClientClaims: '始终发送客户端声明', - alwaysIncludeUserClaimsInIdToken: '始终在标识令牌中包含用户声明', - pairWiseSubjectSalt: '配对主体盐', - requireConsent: '需要同意', - allowRememberConsent: '允许记住同意', - clientUri: '客户端 Uri', - logoUri: '徽标 Uri', - userCodeType: '用户代码类型', - secretType: '密钥类型', - secretValue: '密钥值', - secretHashType: '哈希类型', - hashOnlySharedSecret: '哈希类型仅适用于 SharedSecret 类型', - secretDescription: '密钥说明', - expiration: '过期日期', - claimType: '声明类型', - claimValue: '声明值', - propertyKey: '属性名称', - propertyValue: '属性值', - createApiResource: '添加Api资源', - updateApiResource: '编辑Api资源', - updateApiResourceByName: '编辑Api资源 {name}', - deleteApiResourceByName: '删除Api资源 {name}', - createApiResourceSuccess: 'Api资源 {name} 已添加!', - deleteApiResourceSuccess: 'Api资源 {name} 已删除!', - updateApiResourceSuccess: 'Api资源 {name} 已修改!', - createApiSecret: '添加Api密钥', - deleteApiSecret: '删除Api密钥', - deleteApiSecretByType: '删除Api密钥 {type}', - createApiSecretSuccess: 'Api密钥 {type} 已添加!', - deleteApiSecretSuccess: 'Api密钥 {type} 已删除!', - apiResourceSecret: 'Api 密钥', - createApiScope: '添加Api作用域', - deleteApiScope: '删除Api作用域', - deleteApiScopeByName: '删除Api作用域 {name}', - createApiScopeSuccess: 'Api作用域 {name} 已添加!', - deleteApiScopeSuccess: 'Api作用域 {name} 已删除!', - apiResourceScope: 'Api 作用域', - deleteApiResource: '删除资源', - resourceName: '资源名称', - resourceDisplayName: '显示名称', - enabledResource: '启用资源', - resourceStatus: '资源状态', - resourceDescription: '资源说明', - resourceUserClaims: '用户声明', - apiScopeName: '名称', - apiScopeDisplayName: '显示名称', - apiScopeDescription: '描述', - apiScopeRequired: '必须', - apiScopeEmphasize: '强调', - apiScopeShowInDiscoveryDocument: '在发现文档显示', - createIdentityResource: '添加身份资源', - updateIdentityResource: '编辑身份资源', - identityResourceProperties: '资源属性', - deleteIdentityResource: '删除资源', - updateIdentityResourceByName: '编辑身份资源 {name}', - deleteIdentityResourceByName: '删除身份资源 {name}', - createIdentityResourceSuccess: '身份资源 {name} 已添加!', - deleteIdentityResourceSuccess: '身份资源 {name} 已删除!', - updateIdentityResourceSuccess: '身份资源 {name} 已修改!', - identityResourceRequired: '必须', - identityResourceEmphasize: '强调', - identityResourceShowInDiscoveryDocument: '在发现文档显示', - deleteIdentityPropertyByKey: '是否要删除身份资源属性: {key}', - deleteIdentityPropertySuccess: '身份资源属性: {key} 已删除!', - createIdentityPropertySuccess: '身份资源属性: {key} 已添加!', - createIdentityProperty: '添加身份资源属性' - }, tenant: { createTenant: '创建租户', updateTenant: '编辑租户', diff --git a/vueJs/src/lang/zh.ts b/vueJs/src/lang/zh.ts index ce7a41f99..65015b454 100644 --- a/vueJs/src/lang/zh.ts +++ b/vueJs/src/lang/zh.ts @@ -431,148 +431,6 @@ export default { aggregateJsonPath: 'Json路径', definedAggregatorProviders: '聚合提供者' }, - identityServer: { - otherOpera: '更多操作', - enabled: '启用客户端', - disbled: '停用客户端', - clientStatus: '客户端状态', - deleteClient: '删除客户端', - updateClient: '编辑客户端', - updateClientByName: '编辑客户端 {name}', - deleteClientById: '是否要删除客户端: {id}', - deleteClientSuccess: '客户端: {id} 已删除!', - createClientSuccess: '客户端: {id} 已添加!', - updateClientSuccess: '客户端: {id} 已修改!', - clientClaim: '客户端声明', - clientProperty: '客户端属性', - clientSecret: '客户端密钥', - clientPermission: '客户端权限', - deleteSecret: '删除密钥', - deleteSecretByType: '是否要删除客户端密钥: {type}', - deleteSecretSuccess: '客户端密钥: {type} 已删除!', - createSecretSuccess: '客户端密钥: {type} 已添加!', - createSecret: '添加客户端密钥', - deleteClaim: '删除声明', - deleteClaimByType: '是否要删除客户端声明: {type}', - deleteClaimSuccess: '客户端声明: {type} 已删除!', - createClaimSuccess: '客户端声明: {type} 已添加!', - createClaim: '添加客户端声明', - deleteProperty: '删除属性', - deleteClientPropertyByType: '是否要删除客户端属性: {key}', - deleteClientPropertySuccess: '客户端属性: {key} 已删除!', - createClientPropertySuccess: '客户端属性: {key} 已添加!', - createClientProperty: '添加客户端属性', - createClient: '添加客户端', - clientId: '客户端标识', - clientName: '客户端名称', - description: '客户端说明', - cloneClint: '克隆客户端', - copyAllowedGrantType: '复制客户端授权类型', - copyRedirectUri: '复制客户端重定向Uri', - copyAllowedScope: '复制客户端作用域', - copyClaim: '复制客户端声明', - copyAllowedCorsOrigin: '复制客户端跨域来源', - copyPostLogoutRedirectUri: '复制客户端注销重定向Uri', - copyPropertie: '复制客户端属性', - copyIdentityProviderRestriction: '复制身份提供程序限制', - protocolType: '协议类型', - requireClientSecret: '需要客户端密钥', - requirePkce: '需要Pkce', - allowPlainTextPkce: '允许纯文本Pkce', - allowOfflineAccess: '允许离线访问', - allowedScopes: '允许的作用域', - redirectUris: '重定向Uri', - allowedGrantTypes: '允许的授权类型', - allowAccessTokensViaBrowser: '允许通过浏览器访问令牌', - identityTokenLifetime: '身份令牌有效期(s)', - accessTokenLifetime: '访问令牌有效期(s)', - authorizationCodeLifetime: '授权码有效期(s)', - absoluteRefreshTokenLifetime: '绝对刷新令牌有效期(s)', - slidingRefreshTokenLifetime: '滚动刷新令牌有效期(s)', - deviceCodeLifetime: '设备授权码有效期(s)', - clientClaimsPrefix: '客户端声明前缀', - basicOptions: '基本设置', - frontChannelLogoutUri: '前端通道注销 Uri', - frontChannelLogoutSessionRequired: '需要前端通道注销会话', - backChannelLogoutUri: '后端通道退出 Uri', - backChannelLogoutSessionRequired: '需要后端通道注销会话', - enableLocalLogin: '启用本地登录', - postLogoutRedirectUris: '注销重定向 Uri', - identityProviderRestrictions: '身份提供程序限制', - userSsoLifetime: '用户 SSO 生命周期', - accessTokenType: '访问令牌类型', - refreshTokenUsage: '刷新令牌使用情况', - refreshTokenExpiration: '刷新令牌过期方式', - allowedCorsOrigins: '允许跨域来源', - updateAccessTokenClaimsOnRefresh: '刷新时更新访问令牌声明', - includeJwtId: '包括 Jwt 标识', - alwaysSendClientClaims: '始终发送客户端声明', - alwaysIncludeUserClaimsInIdToken: '始终在标识令牌中包含用户声明', - pairWiseSubjectSalt: '配对主体盐', - requireConsent: '需要同意', - allowRememberConsent: '允许记住同意', - clientUri: '客户端 Uri', - logoUri: '徽标 Uri', - userCodeType: '用户代码类型', - secretType: '密钥类型', - secretValue: '密钥值', - secretHashType: '哈希类型', - hashOnlySharedSecret: '哈希类型仅适用于 SharedSecret 类型', - secretDescription: '密钥说明', - expiration: '过期日期', - claimType: '声明类型', - claimValue: '声明值', - propertyKey: '属性名称', - propertyValue: '属性值', - createApiResource: '添加Api资源', - updateApiResource: '编辑Api资源', - updateApiResourceByName: '编辑Api资源 {name}', - deleteApiResourceByName: '删除Api资源 {name}', - createApiResourceSuccess: 'Api资源 {name} 已添加!', - deleteApiResourceSuccess: 'Api资源 {name} 已删除!', - updateApiResourceSuccess: 'Api资源 {name} 已修改!', - createApiSecret: '添加Api密钥', - deleteApiSecret: '删除Api密钥', - deleteApiSecretByType: '删除Api密钥 {type}', - createApiSecretSuccess: 'Api密钥 {type} 已添加!', - deleteApiSecretSuccess: 'Api密钥 {type} 已删除!', - apiResourceSecret: 'Api 密钥', - createApiScope: '添加Api作用域', - deleteApiScope: '删除Api作用域', - deleteApiScopeByName: '删除Api作用域 {name}', - createApiScopeSuccess: 'Api作用域 {name} 已添加!', - deleteApiScopeSuccess: 'Api作用域 {name} 已删除!', - apiResourceScope: 'Api 作用域', - deleteApiResource: '删除资源', - resourceName: '资源名称', - resourceDisplayName: '显示名称', - enabledResource: '启用资源', - resourceStatus: '资源状态', - resourceDescription: '资源说明', - resourceUserClaims: '用户声明', - apiScopeName: '名称', - apiScopeDisplayName: '显示名称', - apiScopeDescription: '描述', - apiScopeRequired: '必须', - apiScopeEmphasize: '强调', - apiScopeShowInDiscoveryDocument: '在发现文档显示', - createIdentityResource: '添加身份资源', - updateIdentityResource: '编辑身份资源', - identityResourceProperties: '资源属性', - deleteIdentityResource: '删除资源', - updateIdentityResourceByName: '编辑身份资源 {name}', - deleteIdentityResourceByName: '删除身份资源 {name}', - createIdentityResourceSuccess: '身份资源 {name} 已添加!', - deleteIdentityResourceSuccess: '身份资源 {name} 已删除!', - updateIdentityResourceSuccess: '身份资源 {name} 已修改!', - identityResourceRequired: '必须', - identityResourceEmphasize: '强调', - identityResourceShowInDiscoveryDocument: '在发现文档显示', - deleteIdentityPropertyByKey: '是否要删除身份资源属性: {key}', - deleteIdentityPropertySuccess: '身份资源属性: {key} 已删除!', - createIdentityPropertySuccess: '身份资源属性: {key} 已添加!', - createIdentityProperty: '添加身份资源属性' - }, tenant: { createTenant: '创建租户', updateTenant: '编辑租户', diff --git a/vueJs/src/router/modules/identityServer.ts b/vueJs/src/router/modules/identityServer.ts index a8c2cd22b..8fa2887f8 100644 --- a/vueJs/src/router/modules/identityServer.ts +++ b/vueJs/src/router/modules/identityServer.ts @@ -7,7 +7,7 @@ const identityServerRouter: RouteConfig = { meta: { title: 'identityServer', icon: 'identity-server', - roles: ['IdentityServer.Clients', 'IdentityServer.ApiResources', 'IdentityServer.IdentityResources'], + roles: ['AbpIdentityServer.Clients', 'AbpIdentityServer.ApiResources', 'AbpIdentityServer.IdentityResources'], alwaysShow: true }, children: [ @@ -18,7 +18,7 @@ const identityServerRouter: RouteConfig = { meta: { title: 'clients', icon: 'client', - roles: ['IdentityServer.Clients'] + roles: ['AbpIdentityServer.Clients'] } }, { @@ -28,7 +28,7 @@ const identityServerRouter: RouteConfig = { meta: { title: 'apiresources', icon: 'api', - roles: ['IdentityServer.ApiResources'] + roles: ['AbpIdentityServer.ApiResources'] } }, { @@ -38,7 +38,7 @@ const identityServerRouter: RouteConfig = { meta: { title: 'identityresources', icon: 'identity', - roles: ['IdentityServer.IdentityResources'] + roles: ['AbpIdentityServer.IdentityResources'] } } ] diff --git a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue b/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue index 8db253243..c50597a2b 100644 --- a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue +++ b/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceCreateOrEditForm.vue @@ -15,15 +15,14 @@ ref="formApiResource" label-width="100px" :model="apiResource" - :rules="apiResourceRules" > + + + {{ $t('AbpIdentityServer.Advanced') }} + + + + {{ $t('AbpIdentityServer.Scope') }} + + + {{ $t('AbpIdentityServer.Secret') }} + + + {{ $t('AbpIdentityServer.Propertites') }} + + + + + + - {{ $t('table.cancel') }} + {{ $t('AbpIdentityServer.Cancel') }} - {{ $t('table.confirm') }} + {{ $t('AbpIdentityServer.Save') }} @@ -131,21 +190,23 @@ import ApiResourceService, { ApiResourceCreate, ApiResourceUpdate, ApiSecretCreateOrUpdate, - ApiResourceCreateOrUpdate, HashType + ApiResourceCreateOrUpdate } from '@/api/api-resources' import { Component, Prop, Vue, Watch } from 'vue-property-decorator' import ClaimTypeApiService from '@/api/cliam-type' import { checkPermission } from '@/utils/permission' import { dateFormat } from '@/utils/index' import { Claim } from '@/api/types' -import ApiResourceSecretEditForm from './ApiResourceSecretEditForm.vue' import ApiResourceScopeEditForm from './ApiResourceScopeEditForm.vue' +import PropertiesEditForm from '../../components/PropertiesEditForm.vue' +import SecretEditForm from '../../components/SecretEditForm.vue' @Component({ name: 'ApiResourceCreateOrEditForm', components: { - ApiResourceScopeEditForm, - ApiResourceSecretEditForm + SecretEditForm, + PropertiesEditForm, + ApiResourceScopeEditForm }, filters: { dateTimeFilter(datetime: string) { @@ -170,15 +231,11 @@ export default class extends Vue { @Prop({ default: '' }) private apiResourceId!: string - private activeTable = 'infomation' + private activeTabPane = 'basics' + private advancedComponent = 'api-resource-scope-edit-form' private apiResource = new ApiResource() private apiResourceClaims = new Array() private newApiSecret = new ApiSecretCreateOrUpdate() - private apiResourceRules = { - name: [ - { required: true, message: this.l('pleaseInputBy', { key: this.l('AbpIdentityServer.Name') }), trigger: 'blur' } - ] - } get isEdit() { if (this.apiResourceId) { @@ -205,7 +262,7 @@ export default class extends Vue { } private handleGetApiResource() { - this.activeTable = 'infomation' + this.activeTabPane = 'basics' if (this.apiResourceId && this.showDialog) { ApiResourceService.getApiResourceById(this.apiResourceId).then(res => { this.apiResource = res @@ -215,13 +272,13 @@ export default class extends Vue { } } - private apiResourceSecretCreated(hashType: HashType, type: string, value: string, description: string, expiration: Date | undefined) { + private apiResourceSecretCreated(secret: any) { const apiSecret = new ApiSecretCreateOrUpdate() - apiSecret.hashType = hashType - apiSecret.type = type - apiSecret.value = value - apiSecret.description = description - apiSecret.expiration = expiration + apiSecret.hashType = secret.hashType + apiSecret.type = secret.type + apiSecret.value = secret.value + apiSecret.description = secret.description + apiSecret.expiration = secret.expiration this.apiResource.secrets.push(apiSecret) } @@ -239,7 +296,7 @@ export default class extends Vue { apiScope.required = required apiScope.emphasize = emphasize apiScope.showInDiscoveryDocument = showInDiscoveryDocument - apiScope.userClaims = userClaims + apiScope.userClaims.push(...userClaims) this.apiResource.scopes.push(apiScope) } @@ -248,7 +305,12 @@ export default class extends Vue { this.apiResource.scopes.splice(scopeIndex, 1) } - private onSaveApiResource() { + private onDropdownMenuItemChanged(component: any) { + this.activeTabPane = 'avanced' + this.advancedComponent = component + } + + private onSave() { const frmApiResource = this.$refs.formApiResource as any frmApiResource.validate((valid: boolean) => { if (valid) { @@ -283,6 +345,7 @@ export default class extends Vue { apiResource.userClaims = this.apiResource.userClaims apiResource.scopes = this.apiResource.scopes apiResource.secrets = this.apiResource.secrets + apiResource.properties = this.apiResource.properties } private onFormClosed(changed: boolean) { @@ -294,6 +357,14 @@ export default class extends Vue { this.onFormClosed(false) } + private onPropertyCreated(key: string, value: string) { + this.$set(this.apiResource.properties, key, value) + } + + private onPropertyDeleted(key: string) { + this.$delete(this.apiResource.properties, key) + } + public resetFields() { const frmApiResource = this.$refs.formApiResource as any frmApiResource.resetFields() @@ -310,11 +381,13 @@ export default class extends Vue { position: absolute; right: 10px; top: 20px; + width:100px; } .cancel { position: absolute; right: 120px; top: 20px; + width:100px; } .full-select { width: 100%; diff --git a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceScopeEditForm.vue b/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceScopeEditForm.vue index 23eeba250..5eeb6c0ad 100644 --- a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceScopeEditForm.vue +++ b/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceScopeEditForm.vue @@ -2,20 +2,25 @@
- + @@ -103,7 +108,7 @@ label-width="80px" > - + - + - + - + - + - + @@ -145,7 +165,10 @@ :label="$t('AbpIdentityServer.ShowInDiscoveryDocument')" label-width="150px" > - + @@ -204,22 +227,21 @@ export default class ApiResourceScopeEditForm extends Vue { @Prop({ default: () => { return new Array() } }) private apiResourceScopes!: ApiScope[] - private apiResourceScope = new ApiScope() - private apiResourceScopeRules = { - name: [ - { required: true, message: this.l('pleaseInputBy', { key: this.l('AbpIdentityServer.Name') }), trigger: 'blur' } - ] + get readonly() { + return !checkPermission(['AbpIdentityServer.ApiResources.ManageScopes']) } + private apiResourceScope = new ApiScope() + private handleDeleteApiScope(name: string) { - this.$emit('apiResourceScopeDeleted', name) + this.$emit('onScopeDeleted', name) } private onSave() { const apiResourceScopeEditForm = this.$refs.apiResourceScopeEditForm as Form apiResourceScopeEditForm.validate(valid => { if (valid) { - this.$emit('apiResourceScopeCreated', + this.$emit('onScopeCreated', this.apiResourceScope.name, this.apiResourceScope.required, this.apiResourceScope.emphasize, this.apiResourceScope.showInDiscoveryDocument, this.apiResourceScope.userClaims, this.apiResourceScope.displayName, this.apiResourceScope.description) diff --git a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceSecretEditForm.vue b/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceSecretEditForm.vue deleted file mode 100644 index 1c24d26b5..000000000 --- a/vueJs/src/views/admin/identityServer/api-resources/components/ApiResourceSecretEditForm.vue +++ /dev/null @@ -1,250 +0,0 @@ - - - - - diff --git a/vueJs/src/views/admin/identityServer/api-resources/index.vue b/vueJs/src/views/admin/identityServer/api-resources/index.vue index 148c9e269..dd29adb51 100644 --- a/vueJs/src/views/admin/identityServer/api-resources/index.vue +++ b/vueJs/src/views/admin/identityServer/api-resources/index.vue @@ -17,12 +17,12 @@ type="primary" @click="refreshPagedData" > - {{ $t('searchList') }} + {{ $t('AbpIdentityServer.Search') }} {{ $t('AbpIdentityServer.Resource:New') }} @@ -121,7 +121,7 @@ > + + diff --git a/vueJs/src/views/admin/identityServer/client/components/ClientEditForm.vue b/vueJs/src/views/admin/identityServer/client/components/ClientEditForm.vue index 7ae01277b..8a6beb6c6 100644 --- a/vueJs/src/views/admin/identityServer/client/components/ClientEditForm.vue +++ b/vueJs/src/views/admin/identityServer/client/components/ClientEditForm.vue @@ -3,22 +3,26 @@ v-el-draggable-dialog width="800px" :visible="showDialog" - :title="$t('identityServer.updateClientByName', {name: client.clientName})" + :title="title" custom-class="modal-form" :show-close="false" + :close-on-click-modal="false" + :close-on-press-escape="false" @close="onFormClosed(false)" > - - + + - + multiple + filterable + allow-create + clearable + style="width: 100%;" + > + + + + + + + - - + multiple + filterable + allow-create + clearable + class="full-select" + > + + - + - - - + - + multiple + filterable + allow-create + clearable + style="width: 100%;" + > + + - + - + + + + + {{ $t('AbpIdentityServer.Advanced') }} + + + + {{ $t('AbpIdentityServer.Secret') }} + + + {{ $t('AbpIdentityServer.Claims') }} + + + {{ $t('AbpIdentityServer.Propertites') }} + + + + + - {{ $t('table.cancel') }} + {{ $t('AbpIdentityServer.Cancel') }} - {{ $t('table.confirm') }} + {{ $t('AbpIdentityServer.Save') }} @@ -529,100 +694,142 @@ - - diff --git a/vueJs/src/views/admin/identityServer/client/components/ClientPropertyEditForm.vue b/vueJs/src/views/admin/identityServer/client/components/ClientPropertyEditForm.vue deleted file mode 100644 index e84835fa5..000000000 --- a/vueJs/src/views/admin/identityServer/client/components/ClientPropertyEditForm.vue +++ /dev/null @@ -1,199 +0,0 @@ - - - - - diff --git a/vueJs/src/views/admin/identityServer/client/components/ClientSecretEditForm.vue b/vueJs/src/views/admin/identityServer/client/components/ClientSecretEditForm.vue deleted file mode 100644 index 8a32ae580..000000000 --- a/vueJs/src/views/admin/identityServer/client/components/ClientSecretEditForm.vue +++ /dev/null @@ -1,305 +0,0 @@ - - - - - diff --git a/vueJs/src/views/admin/identityServer/client/index.vue b/vueJs/src/views/admin/identityServer/client/index.vue index 3836010bf..1a2a82283 100644 --- a/vueJs/src/views/admin/identityServer/client/index.vue +++ b/vueJs/src/views/admin/identityServer/client/index.vue @@ -17,13 +17,13 @@ type="primary" @click="refreshPagedData" > - {{ $t('searchList') }} + {{ $t('AbpIdentityServer.Search') }} {{ $t('AbpIdentityServer.Client:New') }} @@ -175,10 +175,10 @@ > @@ -241,18 +261,26 @@ diff --git a/vueJs/src/views/admin/identityServer/components/ScopeInput.vue b/vueJs/src/views/admin/identityServer/components/ScopeInput.vue deleted file mode 100644 index ad3a1cebb..000000000 --- a/vueJs/src/views/admin/identityServer/components/ScopeInput.vue +++ /dev/null @@ -1,190 +0,0 @@ - - - - - diff --git a/vueJs/src/views/admin/identityServer/components/SecretEditForm.vue b/vueJs/src/views/admin/identityServer/components/SecretEditForm.vue new file mode 100644 index 000000000..8463a3bf2 --- /dev/null +++ b/vueJs/src/views/admin/identityServer/components/SecretEditForm.vue @@ -0,0 +1,257 @@ + + + + + diff --git a/vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue b/vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue index 3562b9559..71bce69eb 100644 --- a/vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue +++ b/vueJs/src/views/admin/identityServer/identity-resources/components/IdentityResourceCreateOrEditForm.vue @@ -15,15 +15,14 @@ ref="formIdentityResource" label-width="130px" :model="identityResource" - :rules="identityResourceRules" > + + + - {{ $t('global.cancel') }} + {{ $t('AbpIdentityServer.Cancel') }} - {{ $t('global.confirm') }} + {{ $t('AbpIdentityServer.Save') }} @@ -124,15 +141,25 @@