Browse Source

Add `ClaimsMap` to `AbpClaimsPrincipalFactoryOptions`.

pull/18064/head
maliming 3 years ago
parent
commit
fe4129d3e3
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributor.cs
  2. 12
      framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactoryOptions.cs
  3. 53
      framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpDynamicClaimsPrincipalContributorBase.cs
  4. 7
      framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/AbpDynamicClaimsPrincipalContributorBase_Tests.cs
  5. 3
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDynamicClaimsPrincipalContributor.cs

3
framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributor.cs

@ -24,7 +24,6 @@ public class RemoteDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincipal
var dynamicClaimsCache = context.GetRequiredService<RemoteDynamicClaimsPrincipalContributorCache>();
var dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId());
await MapCommonClaimsAsync(identity, dynamicClaims);
await AddDynamicClaims(identity, dynamicClaims);
await AddDynamicClaimsAsync(context, identity, dynamicClaims);
}
}

12
framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimsPrincipalFactoryOptions.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Security.Claims;
using Volo.Abp.Collections;
namespace Volo.Abp.Security.Claims;
@ -13,6 +14,8 @@ public class AbpClaimsPrincipalFactoryOptions
public string RemoteUrl { get; set; }
public Dictionary<string, List<string>> ClaimsMap { get; set; }
public AbpClaimsPrincipalFactoryOptions()
{
Contributors = new TypeList<IAbpClaimsPrincipalContributor>();
@ -31,5 +34,14 @@ public class AbpClaimsPrincipalFactoryOptions
};
RemoteUrl = "/api/account/dynamic-claims";
ClaimsMap = new Dictionary<string, List<string>>()
{
{ AbpClaimTypes.UserName, new List<string> { "preferred_username", "unique_name", ClaimTypes.Name }},
{ AbpClaimTypes.Name, new List<string> { "given_name", ClaimTypes.GivenName }},
{ AbpClaimTypes.SurName, new List<string> { "family_name", ClaimTypes.Surname }},
{ AbpClaimTypes.Role, new List<string> { "role", "roles", ClaimTypes.Role }},
{ AbpClaimTypes.Email, new List<string> { "email", ClaimTypes.Email }},
};
}
}

53
framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpDynamicClaimsPrincipalContributorBase.cs

@ -3,6 +3,7 @@ using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Security.Claims;
@ -11,52 +12,32 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
{
public abstract Task ContributeAsync(AbpClaimsPrincipalContributorContext context);
protected virtual async Task MapCommonClaimsAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
protected virtual async Task AddDynamicClaimsAsync(AbpClaimsPrincipalContributorContext context, ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
{
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.UserName, "preferred_username", "unique_name", ClaimTypes.Name);
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Role, "role", "roles", ClaimTypes.Role);
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Email, "email", ClaimTypes.Email);
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.SurName, "family_name", ClaimTypes.Surname);
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Name, "given_name", ClaimTypes.GivenName);
var options = context.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value;
foreach (var map in options.ClaimsMap)
{
await MapClaimAsync(identity, dynamicClaims, map.Key, map.Value.ToArray());
}
foreach (var claimGroup in dynamicClaims.GroupBy(x => x.Type))
{
identity.RemoveAll(claimGroup.First().Type);
identity.AddClaims(claimGroup.Where(c => c.Value != null).Select(c => new Claim(claimGroup.First().Type, c.Value!)));
}
}
protected virtual Task MapClaimAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims, string abpClaimType, params string[] dynamicClaimTypes)
protected virtual Task MapClaimAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims, string targetClaimType, params string[] sourceClaimTypes)
{
var claims = dynamicClaims.Where(c => dynamicClaimTypes.Contains(c.Type)).ToList();
var claims = dynamicClaims.Where(c => sourceClaimTypes.Contains(c.Type)).ToList();
if (claims.IsNullOrEmpty())
{
return Task.CompletedTask;
}
dynamicClaims.RemoveAll(claims);
identity.RemoveAll(abpClaimType);
identity.AddClaims(claims.Where(c => c.Value != null).Select(c => new Claim(abpClaimType, c.Value!)));
return Task.CompletedTask;;
}
protected virtual Task AddDynamicClaims(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
{
foreach (var claimGroup in dynamicClaims.GroupBy(x => x.Type))
{
if (claimGroup.Count() > 1)
{
identity.RemoveAll(claimGroup.First().Type);
identity.AddClaims(claimGroup.Where(c => c.Value != null).Select(c => new Claim(claimGroup.First().Type, c.Value!)));
}
else
{
var claim = claimGroup.First();
if (claim.Value != null)
{
identity.AddOrReplace(new Claim(claimGroup.First().Type, claim.Value));
}
else
{
identity.RemoveAll(claim.Type);
}
}
}
identity.RemoveAll(targetClaimType);
identity.AddClaims(claims.Where(c => c.Value != null).Select(c => new Claim(targetClaimType, c.Value!)));
return Task.CompletedTask;;
}

7
framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Claims/AbpDynamicClaimsPrincipalContributorBase_Tests.cs

@ -16,8 +16,7 @@ class TestAbpDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincipalContri
var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
Check.NotNull(identity, nameof(identity));
await MapCommonClaimsAsync(identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
await AddDynamicClaims(identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
await AddDynamicClaimsAsync(context, identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
}
}
@ -33,7 +32,7 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
}
[Fact]
public async Task CreateAsync()
public async Task AddDynamicClaimsAsync()
{
var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity());
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.UserName, "test-source-userName"));
@ -45,7 +44,6 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.EmailVerified, "test-source-emailVerified"));
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.PhoneNumber, "test-source-phoneNumber"));
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.PhoneNumberVerified, "test-source-phoneNumberVerified"));
claimsPrincipal.Identities.First().AddClaim(new Claim("my-claim", "test-source-my-claim"));
DynamicClaims.AddRange(new []
@ -68,6 +66,7 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.Name && c.Value == "test-given_name");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.Role && c.Value == "test-role1");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.Role && c.Value == "test-role2");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.Role && c.Value == "test-role3");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.Email && c.Value == "test-email");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.EmailVerified && c.Value == "test-email-verified");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.PhoneNumber && c.Value == "test-source-phoneNumber");

3
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDynamicClaimsPrincipalContributor.cs

@ -36,7 +36,6 @@ public class IdentityDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincip
return;
}
await MapCommonClaimsAsync(identity, dynamicClaims);
await AddDynamicClaims(identity, dynamicClaims);
await AddDynamicClaimsAsync(context, identity, dynamicClaims);
}
}

Loading…
Cancel
Save