diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs index 0ba64417a3..e586e687c3 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfiguration.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.MultiTenancy public TenantConfiguration() { - + } public TenantConfiguration(Guid id, [NotNull] string name) @@ -28,4 +28,4 @@ namespace Volo.Abp.MultiTenancy ConnectionStrings = new ConnectionStrings(); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/AbpSecurityModule.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/AbpSecurityModule.cs index b1cdcb1097..cf517f0de4 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/AbpSecurityModule.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/AbpSecurityModule.cs @@ -1,13 +1,20 @@ -using System; +using System; +using System.Collections.Generic; using System.Text; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; +using Volo.Abp.Security.Claims; using Volo.Abp.Security.Encryption; namespace Volo.Abp.Security { public class AbpSecurityModule : AbpModule { + public override void PostConfigureServices(ServiceConfigurationContext context) + { + AutoAddClaimsPrincipalContributors(context.Services); + } + public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); @@ -41,5 +48,23 @@ namespace Volo.Abp.Security } }); } + + private static void AutoAddClaimsPrincipalContributors(IServiceCollection services) + { + var contributorTypes = new List(); + + services.OnRegistred(context => + { + if (typeof(IAbpClaimsPrincipalContributor).IsAssignableFrom(context.ImplementationType)) + { + contributorTypes.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.Contributors.AddIfNotContains(contributorTypes); + }); + } } } diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalContributorContext.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalContributorContext.cs new file mode 100644 index 0000000000..c0174e3391 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalContributorContext.cs @@ -0,0 +1,23 @@ +using System; +using System.Security.Claims; +using JetBrains.Annotations; + +namespace Volo.Abp.Security.Claims +{ + public class AbpClaimsPrincipalContributorContext + { + [NotNull] + public ClaimsPrincipal ClaimsPrincipal { get; } + + [NotNull] + public IServiceProvider ServiceProvider { get; } + + public AbpClaimsPrincipalContributorContext( + [NotNull] ClaimsPrincipal claimsIdentity, + [NotNull] IServiceProvider serviceProvider) + { + ClaimsPrincipal = claimsIdentity; + ServiceProvider = serviceProvider; + } + } +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactory.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactory.cs new file mode 100644 index 0000000000..b00b38ea8c --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactory.cs @@ -0,0 +1,40 @@ +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Security.Claims +{ + public class AbpClaimsPrincipalFactory : IAbpClaimsPrincipalFactory, ITransientDependency + { + protected IServiceScopeFactory ServiceScopeFactory { get; } + protected AbpClaimsPrincipalFactoryOptions Options { get; } + + public AbpClaimsPrincipalFactory( + IServiceScopeFactory serviceScopeFactory, + IOptions abpClaimOptions) + { + ServiceScopeFactory = serviceScopeFactory; + Options = abpClaimOptions.Value; + } + + public virtual async Task CreateAsync() + { + using (var scope = ServiceScopeFactory.CreateScope()) + { + var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity()); + + var context = new AbpClaimsPrincipalContributorContext(claimsPrincipal, scope.ServiceProvider); + + foreach (var contributorType in Options.Contributors) + { + var contributor = (IAbpClaimsPrincipalContributor) scope.ServiceProvider.GetRequiredService(contributorType); + await contributor.ContributeAsync(context); + } + + return claimsPrincipal; + } + } + } +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactoryOptions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactoryOptions.cs new file mode 100644 index 0000000000..8083a018ee --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactoryOptions.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Collections; + +namespace Volo.Abp.Security.Claims +{ + public class AbpClaimsPrincipalFactoryOptions + { + public ITypeList Contributors { get; } + + public AbpClaimsPrincipalFactoryOptions() + { + Contributors = new TypeList(); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ClaimsIdentityExtensions.cs similarity index 94% rename from modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs rename to framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ClaimsIdentityExtensions.cs index 156f092f9e..bf8bb26784 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ClaimsIdentityExtensions.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/ClaimsIdentityExtensions.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Security.Claims; -namespace Volo.Abp.Identity +namespace Volo.Abp.Security.Claims { public static class ClaimsIdentityExtensions { diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalContributor.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalContributor.cs new file mode 100644 index 0000000000..7b9f6db3f5 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalContributor.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Security.Claims +{ + public interface IAbpClaimsPrincipalContributor + { + Task ContributeAsync(AbpClaimsPrincipalContributorContext context); + } +} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalFactory.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalFactory.cs new file mode 100644 index 0000000000..1de0afbcab --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/IAbpClaimsPrincipalFactory.cs @@ -0,0 +1,10 @@ +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Volo.Abp.Security.Claims +{ + public interface IAbpClaimsPrincipalFactory + { + Task CreateAsync(); + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs index 9831b03d5d..2543e846e6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs @@ -10,21 +10,29 @@ using Volo.Abp.Uow; namespace Volo.Abp.Identity { - public class AbpUserClaimsPrincipalFactory : UserClaimsPrincipalFactory, ITransientDependency + public class AbpUserClaimsPrincipalFactory : UserClaimsPrincipalFactory, + ITransientDependency { + protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; } + protected IAbpClaimsPrincipalFactory AbpClaimsPrincipalFactory { get; } + public AbpUserClaimsPrincipalFactory( UserManager userManager, RoleManager roleManager, - IOptions options) + IOptions options, + ICurrentPrincipalAccessor currentPrincipalAccessor, + IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory) : base( - userManager, - roleManager, - options) + userManager, + roleManager, + options) { + CurrentPrincipalAccessor = currentPrincipalAccessor; + AbpClaimsPrincipalFactory = abpClaimsPrincipalFactory; } [UnitOfWork] - public async override Task CreateAsync(IdentityUser user) + public override async Task CreateAsync(IdentityUser user) { var principal = await base.CreateAsync(user); var identity = principal.Identities.First(); @@ -49,7 +57,8 @@ namespace Volo.Abp.Identity identity.AddIfNotContains(new Claim(AbpClaimTypes.PhoneNumber, user.PhoneNumber)); } - identity.AddIfNotContains(new Claim(AbpClaimTypes.PhoneNumberVerified, user.PhoneNumberConfirmed.ToString())); + identity.AddIfNotContains( + new Claim(AbpClaimTypes.PhoneNumberVerified, user.PhoneNumberConfirmed.ToString())); if (!user.Email.IsNullOrWhiteSpace()) { @@ -58,6 +67,15 @@ namespace Volo.Abp.Identity identity.AddIfNotContains(new Claim(AbpClaimTypes.EmailVerified, user.EmailConfirmed.ToString())); + using (CurrentPrincipalAccessor.Change(identity)) + { + var abpClaimsPrincipal = await AbpClaimsPrincipalFactory.CreateAsync(); + foreach (var claim in abpClaimsPrincipal.Claims) + { + identity.AddIfNotContains(claim); + } + } + return principal; } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs index c60c241209..bfdc8c3957 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs @@ -14,15 +14,9 @@ namespace Volo.Abp.IdentityServer { } - protected override IEnumerable GetOptionalClaims(ClaimsPrincipal subject) + protected override IEnumerable FilterRequestedClaimTypes(IEnumerable claimTypes) { - var tenantClaim = subject.FindFirst(AbpClaimTypes.TenantId); - if (tenantClaim == null) - { - return base.GetOptionalClaims(subject); - } - - return base.GetOptionalClaims(subject).Union(new[] { tenantClaim }); + return base.FilterRequestedClaimTypes(claimTypes).Union(new []{AbpClaimTypes.TenantId, AbpClaimTypes.EditionId}); } } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs index e18e6a219b..982e52cfab 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using IdentityModel; using Microsoft.AspNetCore.Identity; using Volo.Abp.DependencyInjection; -using Volo.Abp.Identity; +using Volo.Abp.Security.Claims; using IdentityUser = Volo.Abp.Identity.IdentityUser; namespace Volo.Abp.IdentityServer.AspNetIdentity