Update `AbpDynamicClaimsPrincipalContributorBase`.

pull/18064/head
maliming 2 years ago
parent a0415c26d7
commit 59a2227ffc

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
@ -59,7 +60,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : ITransientDependency
// Use independent cache for remote claims.
return (await Cache.GetOrAddAsync($"{nameof(RemoteDynamicClaimsPrincipalContributorCache)}{AbpClaimCacheItem.CalculateCacheKey(userId, tenantId)}", async () =>
{
var dynamicClaims = new List<AbpClaimCacheItem>();
var dynamicClaims = AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims.Select(claimType => new AbpClaimCacheItem(claimType, null)).ToList();
Logger.LogDebug($"Get dynamic claims for user: {userId} from remote service.");
try
{
@ -67,7 +68,11 @@ public class RemoteDynamicClaimsPrincipalContributorCache : ITransientDependency
var requestMessage = new HttpRequestMessage(HttpMethod.Get, AbpClaimsPrincipalFactoryOptions.Value.RemoteUrl);
await HttpClientAuthenticator.Authenticate(new RemoteServiceHttpClientAuthenticateContext(client, requestMessage, new RemoteServiceConfiguration("/"), string.Empty));
var response = await client.SendAsync(requestMessage);
dynamicClaims = JsonSerializer.Deserialize<List<AbpClaimCacheItem>>(await response.Content.ReadAsStringAsync());
var remoteClaims = JsonSerializer.Deserialize<List<AbpClaimCacheItem>>(await response.Content.ReadAsStringAsync());
foreach (var claim in dynamicClaims)
{
claim.Value = remoteClaims.FirstOrDefault(c => c.Type == claim.Type)?.Value;
}
Logger.LogDebug($"Successfully got {dynamicClaims.Count} remote claims for user: {userId}");
}
catch (Exception e)

@ -7,9 +7,9 @@ public class AbpClaimCacheItem
{
public string Type { get; set; }
public string Value { get; set; }
public string? Value { get; set; }
public AbpClaimCacheItem(string type, string value)
public AbpClaimCacheItem(string type, string? value)
{
Type = type;
Value = value;

@ -13,41 +13,41 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
protected virtual async Task MapCommonClaimsAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
{
await MapClaimsAsync(identity, dynamicClaims, identity.NameClaimType, "preferred_username");
await MapClaimsAsync(identity, dynamicClaims, identity.NameClaimType, ClaimTypes.Name);
await MapClaimsAsync(identity, dynamicClaims, identity.RoleClaimType, "role");
await MapClaimsAsync(identity, dynamicClaims, identity.RoleClaimType, ClaimTypes.Role);
await MapClaimsAsync(identity, dynamicClaims, "email", ClaimTypes.Email);
await MapClaimsAsync(identity, dynamicClaims, "family_name", ClaimTypes.Surname);
await MapClaimsAsync(identity, dynamicClaims, "given_name", ClaimTypes.GivenName);
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);
}
protected virtual Task MapClaimsAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims, string sourceType, string targetType)
protected virtual Task MapClaimAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims, string abpClaimType, params string[] dynamicClaimTypes)
{
if (sourceType == targetType)
var claims = dynamicClaims.Where(c => dynamicClaimTypes.Contains(c.Type)).ToList();
if (claims.IsNullOrEmpty())
{
return Task.CompletedTask;;
return Task.CompletedTask;
}
if (identity.Claims.Any(c => c.Type == sourceType) && dynamicClaims.All(c => c.Type != sourceType))
foreach (var claimGroup in claims.GroupBy(x => x.Type))
{
var claims = dynamicClaims.Where(c => c.Type == targetType).ToList();
if (!claims.IsNullOrEmpty())
var claim = claimGroup.First();
if (claimGroup.Count() > 1)
{
identity.RemoveAll(sourceType);
identity.AddClaims(claims.Select(c => new Claim(sourceType, c.Value)));
dynamicClaims.RemoveAll(c => c.Type == targetType);
dynamicClaims.RemoveAll(c => c.Type == claim.Type && identity.Claims.All(x => x.Type != claim.Type));
identity.RemoveAll(abpClaimType);
identity.AddClaims(claimGroup.Where(c => c.Value != null).Select(c => new Claim(abpClaimType, c.Value!)));
}
}
if (identity.Claims.Any(c => c.Type == targetType) && dynamicClaims.All(c => c.Type != targetType))
{
var claims = dynamicClaims.Where(c => c.Type == sourceType).ToList();
if (!claims.IsNullOrEmpty())
else
{
identity.RemoveAll(targetType);
identity.AddClaims(claims.Select(c => new Claim(targetType, c.Value)));
dynamicClaims.RemoveAll(c => c.Type == sourceType);
dynamicClaims.RemoveAll(c => c.Type == claim.Type && identity.Claims.All(x => x.Type != claim.Type));
if (claim.Value != null)
{
identity.AddOrReplace(new Claim(abpClaimType, claim.Value));
}
else
{
identity.RemoveAll(abpClaimType);
}
}
}
@ -56,16 +56,24 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
protected virtual Task AddDynamicClaims(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
{
foreach (var claims in dynamicClaims.GroupBy(x => x.Type))
foreach (var claimGroup in dynamicClaims.GroupBy(x => x.Type))
{
if (claims.Count() > 1)
if (claimGroup.Count() > 1)
{
identity.RemoveAll(claims.First().Type);
identity.AddClaims(claims.Select(c => new Claim(claims.First().Type, c.Value)));
identity.RemoveAll(claimGroup.First().Type);
identity.AddClaims(claimGroup.Where(c => c.Value != null).Select(c => new Claim(claimGroup.First().Type, c.Value!)));
}
else
{
identity.AddOrReplace(new Claim(claims.First().Type, claims.First().Value));
var claim = claimGroup.First();
if (claim.Value != null)
{
identity.AddOrReplace(new Claim(claimGroup.First().Type, claim.Value));
}
else
{
identity.RemoveAll(claim.Type);
}
}
}

@ -5,4 +5,10 @@ public class DynamicClaimDto
public string Type { get; set; }
public string Value { get; set; }
public DynamicClaimDto(string type, string value)
{
Type = type;
Value = value;
}
}

@ -29,14 +29,20 @@ public class DynamicClaimsAppService : IdentityAppServiceBase, IDynamicClaimsApp
{
var principal = await AbpClaimsPrincipalFactory.CreateAsync(PrincipalAccessor.Principal);
var dynamicClaims = principal.Claims
.Where(c => AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims.Contains(c.Type))
.Select(c => new DynamicClaimDto
var dynamicClaims = new List<DynamicClaimDto>();
foreach (var claimType in AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims)
{
var claims = principal.Claims.Where(x => x.Type == claimType).ToList();
if (claims.Any())
{
Type = c.Type,
Value = c.Value
});
dynamicClaims.AddRange(claims.Select(claim => new DynamicClaimDto(claimType, claim.Value)));
}
else
{
dynamicClaims.Add(new DynamicClaimDto(claimType, null));
}
}
return dynamicClaims.ToList();
return dynamicClaims;
}
}

@ -55,9 +55,22 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
var user = await UserManager.GetByIdAsync(userId);
var principal = await UserClaimsPrincipalFactory.CreateAsync(user);
return principal.Identities.FirstOrDefault()?.Claims
.Where(c => AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims.Contains(c.Type))
.Select(c => new AbpClaimCacheItem(c.Type, c.Value)).ToList();
var dynamicClaims = new List<AbpClaimCacheItem>();
foreach (var claimType in AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims)
{
var claims = principal.Claims.Where(x => x.Type == claimType).ToList();
if (claims.Any())
{
dynamicClaims.AddRange(claims.Select(claim => new AbpClaimCacheItem(claimType, claim.Value)));
}
else
{
dynamicClaims.Add(new AbpClaimCacheItem(claimType, null));
}
}
return dynamicClaims;
}
}, () => new DistributedCacheEntryOptions
{

Loading…
Cancel
Save