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 dynamicClaimsCache = context.GetRequiredService<RemoteDynamicClaimsPrincipalContributorCache>();
var dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId()); var dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId());
await MapCommonClaimsAsync(identity, dynamicClaims); await AddDynamicClaimsAsync(context, identity, dynamicClaims);
await AddDynamicClaims(identity, dynamicClaims);
} }
} }

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

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims;
using Volo.Abp.Collections; using Volo.Abp.Collections;
namespace Volo.Abp.Security.Claims; namespace Volo.Abp.Security.Claims;
@ -13,6 +14,8 @@ public class AbpClaimsPrincipalFactoryOptions
public string RemoteUrl { get; set; } public string RemoteUrl { get; set; }
public Dictionary<string, List<string>> ClaimsMap { get; set; }
public AbpClaimsPrincipalFactoryOptions() public AbpClaimsPrincipalFactoryOptions()
{ {
Contributors = new TypeList<IAbpClaimsPrincipalContributor>(); Contributors = new TypeList<IAbpClaimsPrincipalContributor>();
@ -31,5 +34,14 @@ public class AbpClaimsPrincipalFactoryOptions
}; };
RemoteUrl = "/api/account/dynamic-claims"; 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.Claims;
using System.Security.Principal; using System.Security.Principal;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Security.Claims; namespace Volo.Abp.Security.Claims;
@ -11,52 +12,32 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
{ {
public abstract Task ContributeAsync(AbpClaimsPrincipalContributorContext context); 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); var options = context.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value;
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Role, "role", "roles", ClaimTypes.Role); foreach (var map in options.ClaimsMap)
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Email, "email", ClaimTypes.Email); {
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.SurName, "family_name", ClaimTypes.Surname); await MapClaimAsync(identity, dynamicClaims, map.Key, map.Value.ToArray());
await MapClaimAsync(identity, dynamicClaims, AbpClaimTypes.Name, "given_name", ClaimTypes.GivenName); }
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()) if (claims.IsNullOrEmpty())
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
dynamicClaims.RemoveAll(claims); dynamicClaims.RemoveAll(claims);
identity.RemoveAll(abpClaimType); identity.RemoveAll(targetClaimType);
identity.AddClaims(claims.Where(c => c.Value != null).Select(c => new Claim(abpClaimType, c.Value!))); identity.AddClaims(claims.Where(c => c.Value != null).Select(c => new Claim(targetClaimType, 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);
}
}
}
return Task.CompletedTask;; 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(); var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
Check.NotNull(identity, nameof(identity)); Check.NotNull(identity, nameof(identity));
await MapCommonClaimsAsync(identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims); await AddDynamicClaimsAsync(context, identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
await AddDynamicClaims(identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
} }
} }
@ -33,7 +32,7 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
} }
[Fact] [Fact]
public async Task CreateAsync() public async Task AddDynamicClaimsAsync()
{ {
var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity()); var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity());
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.UserName, "test-source-userName")); 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.EmailVerified, "test-source-emailVerified"));
claimsPrincipal.Identities.First().AddClaim(new Claim(AbpClaimTypes.PhoneNumber, "test-source-phoneNumber")); 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(AbpClaimTypes.PhoneNumberVerified, "test-source-phoneNumberVerified"));
claimsPrincipal.Identities.First().AddClaim(new Claim("my-claim", "test-source-my-claim")); claimsPrincipal.Identities.First().AddClaim(new Claim("my-claim", "test-source-my-claim"));
DynamicClaims.AddRange(new [] 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.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-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-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.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.EmailVerified && c.Value == "test-email-verified");
claimsPrincipal.Identities.First().Claims.ShouldContain(c => c.Type == AbpClaimTypes.PhoneNumber && c.Value == "test-source-phoneNumber"); 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; return;
} }
await MapCommonClaimsAsync(identity, dynamicClaims); await AddDynamicClaimsAsync(context, identity, dynamicClaims);
await AddDynamicClaims(identity, dynamicClaims);
} }
} }

Loading…
Cancel
Save