Refresh instead of returning dynamic claims.

pull/18064/head
maliming 2 years ago
parent 10ea0e61d3
commit e407754280

@ -1,6 +1,9 @@
using System;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Mvc.Client;
@ -22,8 +25,20 @@ public class RemoteDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincipal
}
var dynamicClaimsCache = context.GetRequiredService<RemoteDynamicClaimsPrincipalContributorCache>();
var dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId());
AbpDynamicClaimCacheItem dynamicClaims;
try
{
dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId());
}
catch (Exception e)
{
// In case if failed refresh remote dynamic cache, We force to clear the claims principal.
context.ClaimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity());
var logger = context.GetRequiredService<ILogger<RemoteDynamicClaimsPrincipalContributor>>();
logger.LogWarning(e, $"Failed to refresh remote dynamic claims cache for user: {userId.Value}");
return;
}
await AddDynamicClaimsAsync(context, identity, dynamicClaims);
await AddDynamicClaimsAsync(context, identity, dynamicClaims.Claims);
}
}

@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
@ -21,76 +19,58 @@ public class RemoteDynamicClaimsPrincipalContributorCache : ITransientDependency
public const string HttpClientName = nameof(RemoteDynamicClaimsPrincipalContributorCache);
public ILogger<RemoteDynamicClaimsPrincipalContributorCache> Logger { get; set; }
protected IDistributedCache<List<AbpClaimCacheItem>> Cache { get; }
protected IDistributedCache<AbpDynamicClaimCacheItem> Cache { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IOptions<AbpClaimsPrincipalFactoryOptions> AbpClaimsPrincipalFactoryOptions { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; }
protected IOptions<RemoteDynamicClaimsPrincipalContributorCacheOptions> CacheOptions { get; }
public RemoteDynamicClaimsPrincipalContributorCache(
IDistributedCache<List<AbpClaimCacheItem>> cache,
IDistributedCache<AbpDynamicClaimCacheItem> cache,
IHttpClientFactory httpClientFactory,
IOptions<AbpClaimsPrincipalFactoryOptions> abpClaimsPrincipalFactoryOptions,
IJsonSerializer jsonSerializer,
IRemoteServiceHttpClientAuthenticator httpClientAuthenticator,
IOptions<RemoteDynamicClaimsPrincipalContributorCacheOptions> cacheOptions)
IRemoteServiceHttpClientAuthenticator httpClientAuthenticator)
{
Cache = cache;
HttpClientFactory = httpClientFactory;
AbpClaimsPrincipalFactoryOptions = abpClaimsPrincipalFactoryOptions;
JsonSerializer = jsonSerializer;
HttpClientAuthenticator = httpClientAuthenticator;
CacheOptions = cacheOptions;
Logger = NullLogger<RemoteDynamicClaimsPrincipalContributorCache>.Instance;
}
public virtual async Task<List<AbpClaimCacheItem>> GetAsync(Guid userId, Guid? tenantId = null)
public virtual async Task<AbpDynamicClaimCacheItem> GetAsync(Guid userId, Guid? tenantId = null)
{
Logger.LogDebug($"Get dynamic claims cache for user: {userId}");
//The UI may use the same cache as AuthServer in the tiered application.
var claims = await Cache.GetAsync(AbpClaimCacheItem.CalculateCacheKey(userId, tenantId));
if (!claims.IsNullOrEmpty())
var claims = await Cache.GetAsync(AbpDynamicClaimCacheItem.CalculateCacheKey(userId, tenantId));
if (claims != null && !claims.Claims.IsNullOrEmpty())
{
return claims!;
return claims;
}
Logger.LogDebug($"Get dynamic claims cache for user: {userId} from remote cache.");
// Use independent cache for remote claims.
return (await Cache.GetOrAddAsync($"{nameof(RemoteDynamicClaimsPrincipalContributorCache)}{AbpClaimCacheItem.CalculateCacheKey(userId, tenantId)}", async () =>
Logger.LogDebug($"Refresh dynamic claims for user: {userId} from remote service.");
try
{
var dynamicClaims = AbpClaimsPrincipalFactoryOptions.Value.DynamicClaims.Select(claimType => new AbpClaimCacheItem(claimType, null)).ToList();
Logger.LogDebug($"Get dynamic claims for user: {userId} from remote service.");
try
{
var client = HttpClientFactory.CreateClient(HttpClientName);
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);
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)
{
Logger.LogWarning(e, $"Failed to get remote claims for user: {userId}");
}
return dynamicClaims;
}, () => new DistributedCacheEntryOptions
var client = HttpClientFactory.CreateClient(HttpClientName);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, AbpClaimsPrincipalFactoryOptions.Value.RemoteRefreshUrl);
await HttpClientAuthenticator.Authenticate(new RemoteServiceHttpClientAuthenticateContext(client, requestMessage, new RemoteServiceConfiguration("/"), string.Empty));
var response = await client.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
}
catch (Exception e)
{
AbsoluteExpirationRelativeToNow = CacheOptions.Value.CacheAbsoluteExpiration
}))!;
}
Logger.LogWarning(e, $"Failed to refresh remote claims for user: {userId}");
throw;
}
public virtual async Task ClearAsync(Guid userId, Guid? tenantId = null)
{
Logger.LogDebug($"Clear dynamic claims cache for user: {userId}");
Logger.LogDebug($"Clear dynamic claims cache from remote cache for user: {userId}");
await Cache.RemoveAsync(AbpClaimCacheItem.CalculateCacheKey(userId, tenantId));
await Cache.RemoveAsync($"{nameof(RemoteDynamicClaimsPrincipalContributorCache)}{AbpClaimCacheItem.CalculateCacheKey(userId, tenantId)}");
claims = await Cache.GetAsync(AbpDynamicClaimCacheItem.CalculateCacheKey(userId, tenantId));
if (claims == null || claims.Claims.IsNullOrEmpty())
{
throw new AbpException($"Failed to refresh remote claims for user: {userId}");
}
return claims!;
}
}

@ -1,13 +0,0 @@
using System;
namespace Volo.Abp.AspNetCore.Mvc.Client;
public class RemoteDynamicClaimsPrincipalContributorCacheOptions
{
public TimeSpan CacheAbsoluteExpiration { get; set; }
public RemoteDynamicClaimsPrincipalContributorCacheOptions()
{
CacheAbsoluteExpiration = TimeSpan.FromSeconds(60);
}
}

@ -1,9 +1,9 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Security.Claims;
@ -11,11 +11,13 @@ public class AbpDynamicClaimsMiddleware : IMiddleware, ITransientDependency
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var currentUser = context.RequestServices.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
if (context.User.Identity?.IsAuthenticated == true)
{
var abpClaimsPrincipalFactory = context.RequestServices.GetRequiredService<IAbpClaimsPrincipalFactory>();
context.User = await abpClaimsPrincipalFactory.CreateDynamicAsync(context.User);
if (context.RequestServices.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value.IsDynamicClaimsEnabled)
{
var abpClaimsPrincipalFactory = context.RequestServices.GetRequiredService<IAbpClaimsPrincipalFactory>();
context.User = await abpClaimsPrincipalFactory.CreateDynamicAsync(context.User);
}
}
await next(context);

@ -1,22 +0,0 @@
using System;
namespace Volo.Abp.Security.Claims;
[Serializable]
public class AbpClaimCacheItem
{
public string Type { get; set; }
public string? Value { get; set; }
public AbpClaimCacheItem(string type, string? value)
{
Type = type;
Value = value;
}
public static string CalculateCacheKey(Guid userId, Guid? tenantId)
{
return $"{tenantId}-{userId}";
}
}

@ -12,10 +12,12 @@ public class AbpClaimsPrincipalFactoryOptions
public List<string> DynamicClaims { get; }
public string RemoteUrl { get; set; }
public string RemoteRefreshUrl { get; set; }
public Dictionary<string, List<string>> ClaimsMap { get; set; }
public bool IsDynamicClaimsEnabled { get; set; }
public AbpClaimsPrincipalFactoryOptions()
{
Contributors = new TypeList<IAbpClaimsPrincipalContributor>();
@ -33,7 +35,7 @@ public class AbpClaimsPrincipalFactoryOptions
AbpClaimTypes.PhoneNumberVerified
};
RemoteUrl = "/api/account/dynamic-claims";
RemoteRefreshUrl = "/api/account/dynamic-claims/refresh";
ClaimsMap = new Dictionary<string, List<string>>()
{
@ -43,5 +45,7 @@ public class AbpClaimsPrincipalFactoryOptions
{ AbpClaimTypes.Role, new List<string> { "role", "roles", ClaimTypes.Role }},
{ AbpClaimTypes.Email, new List<string> { "email", ClaimTypes.Email }},
};
IsDynamicClaimsEnabled = false;
}
}

@ -0,0 +1,17 @@
using System;
namespace Volo.Abp.Security.Claims;
[Serializable]
public class AbpDynamicClaim
{
public string Type { get; set; }
public string? Value { get; set; }
public AbpDynamicClaim(string type, string? value)
{
Type = type;
Value = value;
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Security.Claims;
[Serializable]
public class AbpDynamicClaimCacheItem
{
public List<AbpDynamicClaim> Claims { get; set; }
public AbpDynamicClaimCacheItem()
{
Claims = new List<AbpDynamicClaim>();
}
public AbpDynamicClaimCacheItem(List<AbpDynamicClaim> claims)
{
Claims = claims;
}
public static string CalculateCacheKey(Guid userId, Guid? tenantId)
{
return $"{tenantId}-{userId}";
}
}

@ -12,7 +12,7 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
{
public abstract Task ContributeAsync(AbpClaimsPrincipalContributorContext context);
protected virtual async Task AddDynamicClaimsAsync(AbpClaimsPrincipalContributorContext context, ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims)
protected virtual async Task AddDynamicClaimsAsync(AbpClaimsPrincipalContributorContext context, ClaimsIdentity identity, List<AbpDynamicClaim> dynamicClaims)
{
var options = context.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value;
foreach (var map in options.ClaimsMap)
@ -27,7 +27,7 @@ public abstract class AbpDynamicClaimsPrincipalContributorBase : IAbpDynamicClai
}
}
protected virtual Task MapClaimAsync(ClaimsIdentity identity, List<AbpClaimCacheItem> dynamicClaims, string targetClaimType, params string[] sourceClaimTypes)
protected virtual Task MapClaimAsync(ClaimsIdentity identity, List<AbpDynamicClaim> dynamicClaims, string targetClaimType, params string[] sourceClaimTypes)
{
var claims = dynamicClaims.Where(c => sourceClaimTypes.Contains(c.Type)).ToList();
if (claims.IsNullOrEmpty())

@ -16,7 +16,7 @@ class TestAbpDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincipalContri
var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
Check.NotNull(identity, nameof(identity));
await AddDynamicClaimsAsync(context, identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims);
await AddDynamicClaimsAsync(context, identity, AbpDynamicClaimsPrincipalContributorBase_Tests.DynamicClaims.Claims);
}
}
@ -24,7 +24,7 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
{
private readonly TestAbpDynamicClaimsPrincipalContributor _dynamicClaimsPrincipalContributorBase = new TestAbpDynamicClaimsPrincipalContributor();
public readonly static List<AbpClaimCacheItem> DynamicClaims = new List<AbpClaimCacheItem>();
public readonly static AbpDynamicClaimCacheItem DynamicClaims = new AbpDynamicClaimCacheItem();
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
@ -46,17 +46,17 @@ public class AbpDynamicClaimsPrincipalContributorBase_Tests : AbpIntegratedTest<
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 []
DynamicClaims.Claims.AddRange(new []
{
new AbpClaimCacheItem("preferred_username", "test-preferred_username"),
new AbpClaimCacheItem(ClaimTypes.GivenName, "test-given_name"),
new AbpClaimCacheItem("family_name", "test-family_name"),
new AbpClaimCacheItem("role", "test-role1"),
new AbpClaimCacheItem("roles", "test-role2"),
new AbpClaimCacheItem(ClaimTypes.Role, "test-role3"),
new AbpClaimCacheItem("email", "test-email"),
new AbpClaimCacheItem(AbpClaimTypes.EmailVerified, "test-email-verified"),
new AbpClaimCacheItem(AbpClaimTypes.PhoneNumberVerified, null),
new AbpDynamicClaim("preferred_username", "test-preferred_username"),
new AbpDynamicClaim(ClaimTypes.GivenName, "test-given_name"),
new AbpDynamicClaim("family_name", "test-family_name"),
new AbpDynamicClaim("role", "test-role1"),
new AbpDynamicClaim("roles", "test-role2"),
new AbpDynamicClaim(ClaimTypes.Role, "test-role3"),
new AbpDynamicClaim("email", "test-email"),
new AbpDynamicClaim(AbpClaimTypes.EmailVerified, "test-email-verified"),
new AbpDynamicClaim(AbpClaimTypes.PhoneNumberVerified, null),
});
await _dynamicClaimsPrincipalContributorBase.ContributeAsync(new AbpClaimsPrincipalContributorContext(claimsPrincipal, GetRequiredService<IServiceProvider>()));

@ -6,5 +6,5 @@ namespace Volo.Abp.Account;
public interface IDynamicClaimsAppService : IApplicationService
{
Task<List<DynamicClaimDto>> GetAsync();
Task RefreshAsync();
}

@ -1,48 +1,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
namespace Volo.Abp.Account;
[Authorize]
public class DynamicClaimsAppService : IdentityAppServiceBase, IDynamicClaimsAppService
{
protected IdentityDynamicClaimsPrincipalContributorCache IdentityDynamicClaimsPrincipalContributorCache { get; }
protected IAbpClaimsPrincipalFactory AbpClaimsPrincipalFactory { get; }
protected ICurrentPrincipalAccessor PrincipalAccessor { get; }
protected IOptions<AbpClaimsPrincipalFactoryOptions> AbpClaimsPrincipalFactoryOptions { get; }
public DynamicClaimsAppService(
IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache,
IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory,
ICurrentPrincipalAccessor principalAccessor,
IOptions<AbpClaimsPrincipalFactoryOptions> abpClaimsPrincipalFactoryOptions)
ICurrentPrincipalAccessor principalAccessor)
{
IdentityDynamicClaimsPrincipalContributorCache = identityDynamicClaimsPrincipalContributorCache;
AbpClaimsPrincipalFactory = abpClaimsPrincipalFactory;
PrincipalAccessor = principalAccessor;
AbpClaimsPrincipalFactoryOptions = abpClaimsPrincipalFactoryOptions;
}
public virtual async Task<List<DynamicClaimDto>> GetAsync()
public virtual async Task RefreshAsync()
{
var principal = await AbpClaimsPrincipalFactory.CreateAsync(PrincipalAccessor.Principal);
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())
{
dynamicClaims.AddRange(claims.Select(claim => new DynamicClaimDto(claimType, claim.Value)));
}
else
{
dynamicClaims.Add(new DynamicClaimDto(claimType, null));
}
}
return dynamicClaims;
await IdentityDynamicClaimsPrincipalContributorCache.ClearAsync(CurrentUser.GetId(), CurrentUser.TenantId);
await AbpClaimsPrincipalFactory.CreateDynamicAsync(PrincipalAccessor.Principal);
}
}

@ -17,8 +17,8 @@ namespace Volo.Abp.Account;
[ExposeServices(typeof(IDynamicClaimsAppService), typeof(DynamicClaimsClientProxy))]
public partial class DynamicClaimsClientProxy : ClientProxyBase<IDynamicClaimsAppService>, IDynamicClaimsAppService
{
public virtual async Task<List<DynamicClaimDto>> GetAsync()
public virtual async Task RefreshAsync()
{
return await RequestAsync<List<DynamicClaimDto>>(nameof(GetAsync));
await RequestAsync(nameof(RefreshAsync));
}
}

@ -351,28 +351,28 @@
"name": "IDynamicClaimsAppService",
"methods": [
{
"name": "GetAsync",
"name": "RefreshAsync",
"parametersOnMethod": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Abp.Account.DynamicClaimDto>",
"typeSimple": "[Volo.Abp.Account.DynamicClaimDto]"
"type": "System.Void",
"typeSimple": "System.Void"
}
}
]
}
],
"actions": {
"GetAsync": {
"uniqueName": "GetAsync",
"name": "GetAsync",
"httpMethod": "GET",
"url": "api/account/dynamic-claims",
"RefreshAsync": {
"uniqueName": "RefreshAsync",
"name": "RefreshAsync",
"httpMethod": "POST",
"url": "api/account/dynamic-claims/refresh",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Abp.Account.DynamicClaimDto>",
"typeSimple": "[Volo.Abp.Account.DynamicClaimDto]"
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Account.IDynamicClaimsAppService"

@ -18,9 +18,10 @@ public class DynamicClaimsController : AbpControllerBase, IDynamicClaimsAppServi
DynamicClaimsAppService = dynamicClaimsAppService;
}
[HttpGet]
public virtual Task<List<DynamicClaimDto>> GetAsync()
[HttpPost]
[Route("refresh")]
public virtual Task RefreshAsync()
{
return DynamicClaimsAppService.GetAsync();
return DynamicClaimsAppService.RefreshAsync();
}
}

@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
@ -22,7 +20,7 @@ public class IdentityDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincip
}
var dynamicClaimsCache = context.GetRequiredService<IdentityDynamicClaimsPrincipalContributorCache>();
List<AbpClaimCacheItem> dynamicClaims;
AbpDynamicClaimCacheItem dynamicClaims;
try
{
dynamicClaims = await dynamicClaimsCache.GetAsync(userId.Value, identity.FindTenantId());
@ -36,6 +34,6 @@ public class IdentityDynamicClaimsPrincipalContributor : AbpDynamicClaimsPrincip
return;
}
await AddDynamicClaimsAsync(context, identity, dynamicClaims);
await AddDynamicClaimsAsync(context, identity, dynamicClaims.Claims);
}
}

@ -18,7 +18,7 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
{
public ILogger<IdentityDynamicClaimsPrincipalContributorCache> Logger { get; set; }
protected IDistributedCache<List<AbpClaimCacheItem>> Cache { get; }
protected IDistributedCache<AbpDynamicClaimCacheItem> Cache { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IdentityUserManager UserManager { get; }
protected IUserClaimsPrincipalFactory<IdentityUser> UserClaimsPrincipalFactory { get; }
@ -26,7 +26,7 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
protected IOptions<IdentityDynamicClaimsPrincipalContributorCacheOptions> CacheOptions { get; }
public IdentityDynamicClaimsPrincipalContributorCache(
IDistributedCache<List<AbpClaimCacheItem>> cache,
IDistributedCache<AbpDynamicClaimCacheItem> cache,
ICurrentTenant currentTenant,
IdentityUserManager userManager,
IUserClaimsPrincipalFactory<IdentityUser> userClaimsPrincipalFactory,
@ -43,11 +43,11 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
Logger = NullLogger<IdentityDynamicClaimsPrincipalContributorCache>.Instance;
}
public virtual async Task<List<AbpClaimCacheItem>> GetAsync(Guid userId, Guid? tenantId = null)
public virtual async Task<AbpDynamicClaimCacheItem> GetAsync(Guid userId, Guid? tenantId = null)
{
Logger.LogDebug($"Get dynamic claims cache for user: {userId}");
return await Cache.GetOrAddAsync(AbpClaimCacheItem.CalculateCacheKey(userId, tenantId), async () =>
return await Cache.GetOrAddAsync(AbpDynamicClaimCacheItem.CalculateCacheKey(userId, tenantId), async () =>
{
using (CurrentTenant.Change(tenantId))
{
@ -56,17 +56,17 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
var user = await UserManager.GetByIdAsync(userId);
var principal = await UserClaimsPrincipalFactory.CreateAsync(user);
var dynamicClaims = new List<AbpClaimCacheItem>();
var dynamicClaims = new AbpDynamicClaimCacheItem();
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)));
dynamicClaims.Claims.AddRange(claims.Select(claim => new AbpDynamicClaim(claimType, claim.Value)));
}
else
{
dynamicClaims.Add(new AbpClaimCacheItem(claimType, null));
dynamicClaims.Claims.Add(new AbpDynamicClaim(claimType, null));
}
}
@ -81,6 +81,6 @@ public class IdentityDynamicClaimsPrincipalContributorCache : ITransientDependen
public virtual async Task ClearAsync(Guid userId, Guid? tenantId = null)
{
Logger.LogDebug($"Clearing dynamic claims cache for user: {userId}");
await Cache.RemoveAsync(AbpClaimCacheItem.CalculateCacheKey(userId, tenantId));
await Cache.RemoveAsync(AbpDynamicClaimCacheItem.CalculateCacheKey(userId, tenantId));
}
}

@ -32,6 +32,7 @@ using Volo.Abp.DistributedLocking;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.OpenIddict;
using Volo.Abp.Security.Claims;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.UI;
using Volo.Abp.VirtualFileSystem;
@ -180,6 +181,11 @@ public class MyProjectNameAuthServerModule : AbpModule
.AllowCredentials();
});
});
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

@ -231,7 +231,8 @@ public class MyProjectNameBlazorModule : AbpModule
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.RemoteUrl = configuration["AuthServer:Authority"] + options.RemoteUrl;
options.IsDynamicClaimsEnabled = true;
options.RemoteRefreshUrl = configuration["AuthServer:Authority"] + options.RemoteRefreshUrl;
});
}

@ -34,6 +34,7 @@ using Volo.Abp.AutoMapper;
using Volo.Abp.Identity.Blazor.Server;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.Blazor.Server;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement.Blazor.Server;
@ -122,6 +123,10 @@ public class MyProjectNameBlazorModule : AbpModule
private void ConfigureAuthentication(ServiceConfigurationContext context)
{
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureUrls(IConfiguration configuration)

@ -84,7 +84,8 @@ public class MyProjectNameBlazorModule : AbpModule
builder.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.RemoteUrl = builder.Configuration["AuthServer:Authority"] + options.RemoteUrl;
options.IsDynamicClaimsEnabled = true;
options.RemoteRefreshUrl = builder.Configuration["AuthServer:Authority"] + options.RemoteRefreshUrl;
});
}

@ -27,6 +27,7 @@ using Volo.Abp.DistributedLocking;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Swashbuckle;
using Volo.Abp.VirtualFileSystem;
@ -106,6 +107,11 @@ public class MyProjectNameHttpApiHostModule : AbpModule
options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata");
options.Audience = "MyProjectName";
});
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)

@ -25,6 +25,7 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Swashbuckle;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
@ -74,6 +75,10 @@ public class MyProjectNameHttpApiHostModule : AbpModule
private void ConfigureAuthentication(ServiceConfigurationContext context)
{
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureBundles()

@ -211,10 +211,11 @@ public class MyProjectNameWebModule : AbpModule
});
}
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.RemoteUrl = configuration["AuthServer:Authority"] + options.RemoteUrl;
});
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
options.RemoteRefreshUrl = configuration["AuthServer:Authority"] + options.RemoteRefreshUrl;
});
}
private void ConfigureAutoMapper()

@ -30,6 +30,7 @@ using Volo.Abp.Identity.Web;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Web;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.Web;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement.Web;
@ -115,6 +116,10 @@ public class MyProjectNameWebModule : AbpModule
private void ConfigureAuthentication(ServiceConfigurationContext context)
{
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureUrls(IConfiguration configuration)

Loading…
Cancel
Save