Use IDistributedCache in AbpCorsPolicyService,ClientStore,ResourceStore.

Resolve #6969
https://identityserver4.readthedocs.io/en/latest/reference/options.html#caching
pull/7856/head
maliming 5 years ago
parent 101d3549c4
commit 7cc725ffa9

@ -5,6 +5,9 @@ using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Configuration;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IdentityServer.Clients;
@ -16,19 +19,26 @@ namespace Volo.Abp.IdentityServer
public ILogger<AbpCorsPolicyService> Logger { get; set; }
protected IHybridServiceScopeFactory HybridServiceScopeFactory { get; }
protected IDistributedCache<AllowedCorsOriginsCacheItem> Cache { get; }
protected IdentityServerOptions Options { get; }
public AbpCorsPolicyService(
IDistributedCache<AllowedCorsOriginsCacheItem> cache,
IHybridServiceScopeFactory hybridServiceScopeFactory)
IHybridServiceScopeFactory hybridServiceScopeFactory,
IOptions<IdentityServerOptions> options)
{
Cache = cache;
HybridServiceScopeFactory = hybridServiceScopeFactory;
Options = options.Value;
Logger = NullLogger<AbpCorsPolicyService>.Instance;
}
public virtual async Task<bool> IsOriginAllowedAsync(string origin)
{
var cacheItem = await Cache.GetOrAddAsync(AllowedCorsOriginsCacheItem.AllOrigins, CreateCacheItemAsync);
var cacheItem = await Cache.GetOrAddAsync(AllowedCorsOriginsCacheItem.AllOrigins, CreateCacheItemAsync,
() => new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = Options.Caching.CorsExpiration
});
var isAllowed = cacheItem.AllowedOrigins.Contains(origin, StringComparer.OrdinalIgnoreCase);

@ -1,5 +1,9 @@
using System.Threading.Tasks;
using IdentityServer4.Configuration;
using IdentityServer4.Stores;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Volo.Abp.Caching;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.IdentityServer.Clients
@ -8,17 +12,39 @@ namespace Volo.Abp.IdentityServer.Clients
{
protected IClientRepository ClientRepository { get; }
protected IObjectMapper<AbpIdentityServerDomainModule> ObjectMapper { get; }
protected IDistributedCache<IdentityServer4.Models.Client> Cache { get; }
protected IdentityServerOptions Options { get; }
public ClientStore(IClientRepository clientRepository, IObjectMapper<AbpIdentityServerDomainModule> objectMapper)
public ClientStore(
IClientRepository clientRepository,
IObjectMapper<AbpIdentityServerDomainModule> objectMapper,
IDistributedCache<IdentityServer4.Models.Client> cache,
IOptions<IdentityServerOptions> options)
{
ClientRepository = clientRepository;
ObjectMapper = objectMapper;
Cache = cache;
Options = options.Value;
}
public virtual async Task<IdentityServer4.Models.Client> FindClientByIdAsync(string clientId)
{
var client = await ClientRepository.FindByClientIdAsync(clientId);
return ObjectMapper.Map<Client, IdentityServer4.Models.Client>(client);
return await GetCacheItemAsync(clientId);
}
protected virtual async Task<IdentityServer4.Models.Client> GetCacheItemAsync(string clientId)
{
return await Cache.GetOrAddAsync(clientId, async () =>
{
var client = await ClientRepository.FindByClientIdAsync(clientId);
return ObjectMapper.Map<Client, IdentityServer4.Models.Client>(client);
},
optionsFactory: () => new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = Options.Caching.ClientStoreExpiration
},
considerUow: true);
}
}
}

@ -0,0 +1,74 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.IdentityResources;
namespace Volo.Abp.IdentityServer
{
public class IdentityServerCacheItemInvalidator :
ILocalEventHandler<EntityChangedEventData<Client>>,
ILocalEventHandler<EntityChangedEventData<ClientCorsOrigin>>,
ILocalEventHandler<EntityChangedEventData<IdentityResource>>,
ILocalEventHandler<EntityChangedEventData<ApiResource>>,
ILocalEventHandler<EntityChangedEventData<ApiScope>>,
ITransientDependency
{
protected IServiceProvider ServiceProvider { get; }
public IdentityServerCacheItemInvalidator(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public virtual async Task HandleEventAsync(EntityChangedEventData<Client> eventData)
{
var clientCache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.Client>>();
await clientCache.RemoveAsync(eventData.Entity.ClientId);
var corsCache = ServiceProvider.GetRequiredService<IDistributedCache<AllowedCorsOriginsCacheItem>>();
await corsCache.RemoveAsync(AllowedCorsOriginsCacheItem.AllOrigins);
}
public async Task HandleEventAsync(EntityChangedEventData<ClientCorsOrigin> eventData)
{
var corsCache = ServiceProvider.GetRequiredService<IDistributedCache<AllowedCorsOriginsCacheItem>>();
await corsCache.RemoveAsync(AllowedCorsOriginsCacheItem.AllOrigins);
}
public virtual async Task HandleEventAsync(EntityChangedEventData<IdentityResource> eventData)
{
var cache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.IdentityResource>>();
await cache.RemoveAsync(eventData.Entity.Name);
var resourcesCache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.Resources>>();
await resourcesCache.RemoveAsync(ResourceStore.AllResourcesKey);
}
public virtual async Task HandleEventAsync(EntityChangedEventData<ApiResource> eventData)
{
var cache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.ApiResource>>();
await cache.RemoveAsync(ResourceStore.ApiResourceNameCacheKeyPrefix + eventData.Entity.Name);
await cache.RemoveManyAsync(eventData.Entity.Scopes.Select(x => ResourceStore.ApiResourceScopeNameCacheKeyPrefix + x.Scope));
var resourcesCache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.Resources>>();
await resourcesCache.RemoveAsync(ResourceStore.AllResourcesKey);
}
public virtual async Task HandleEventAsync(EntityChangedEventData<ApiScope> eventData)
{
var cache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.ApiScope>>();
await cache.RemoveAsync(eventData.Entity.Name);
var resourcesCache = ServiceProvider.GetRequiredService<IDistributedCache<IdentityServer4.Models.Resources>>();
await resourcesCache.RemoveAsync(ResourceStore.AllResourcesKey);
}
}
}

@ -1,32 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Configuration;
using IdentityServer4.Models;
using IdentityServer4.Stores;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Volo.Abp.Caching;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.IdentityResources;
using Volo.Abp.ObjectMapping;
using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource;
using ApiScope = Volo.Abp.IdentityServer.ApiScopes.ApiScope;
using IdentityResource = Volo.Abp.IdentityServer.IdentityResources.IdentityResource;
namespace Volo.Abp.IdentityServer
{
public class ResourceStore : IResourceStore
{
public const string AllResourcesKey = "AllResources";
public const string ApiResourceNameCacheKeyPrefix = "ApiResourceName_";
public const string ApiResourceScopeNameCacheKeyPrefix = "ApiResourceScopeName_";
protected IIdentityResourceRepository IdentityResourceRepository { get; }
protected IApiResourceRepository ApiResourceRepository { get; }
protected IApiScopeRepository ApiScopeRepository { get; }
protected IObjectMapper<AbpIdentityServerDomainModule> ObjectMapper { get; }
protected IDistributedCache<IdentityServer4.Models.IdentityResource> IdentityResourceCache { get; }
protected IDistributedCache<IdentityServer4.Models.ApiScope> ApiScopeCache { get; }
protected IDistributedCache<IdentityServer4.Models.ApiResource> ApiResourceCache { get; }
protected IDistributedCache<IdentityServer4.Models.Resources> ResourcesCache { get; }
protected IdentityServerOptions Options { get; }
public ResourceStore(
IIdentityResourceRepository identityResourceRepository,
IObjectMapper<AbpIdentityServerDomainModule> objectMapper,
IApiResourceRepository apiResourceRepository,
IApiScopeRepository apiScopeRepository)
IApiScopeRepository apiScopeRepository,
IDistributedCache<IdentityServer4.Models.IdentityResource> identityResourceCache,
IDistributedCache<IdentityServer4.Models.ApiScope> apiScopeCache,
IDistributedCache<IdentityServer4.Models.ApiResource> apiResourceCache,
IDistributedCache<Resources> resourcesCache,
IOptions<IdentityServerOptions> options)
{
IdentityResourceRepository = identityResourceRepository;
ObjectMapper = objectMapper;
ApiResourceRepository = apiResourceRepository;
ApiScopeRepository = apiScopeRepository;
IdentityResourceCache = identityResourceCache;
ApiScopeCache = apiScopeCache;
ApiResourceCache = apiResourceCache;
ResourcesCache = resourcesCache;
Options = options.Value;
}
/// <summary>
@ -34,8 +61,14 @@ namespace Volo.Abp.IdentityServer
/// </summary>
public virtual async Task<IEnumerable<IdentityServer4.Models.IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
{
var resource = await IdentityResourceRepository.GetListByScopeNameAsync(scopeNames.ToArray(), includeDetails: true);
return ObjectMapper.Map<List<Volo.Abp.IdentityServer.IdentityResources.IdentityResource>, List<IdentityServer4.Models.IdentityResource>>(resource);
return await GetCacheItemsAsync(
IdentityResourceCache,
scopeNames,
async keys => await IdentityResourceRepository.GetListByScopeNameAsync(keys, includeDetails: true),
(models, cacheKeyPrefix)=> new List<IEnumerable<KeyValuePair<string, IdentityServer4.Models.IdentityResource>>>
{
models.Select(x => new KeyValuePair<string, IdentityServer4.Models.IdentityResource>(AddCachePrefix(x.Name, cacheKeyPrefix), x))
});
}
/// <summary>
@ -43,8 +76,14 @@ namespace Volo.Abp.IdentityServer
/// </summary>
public virtual async Task<IEnumerable<IdentityServer4.Models.ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
{
var scopes = await ApiScopeRepository.GetListByNameAsync(scopeNames.ToArray(), includeDetails: true);
return ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiScopes.ApiScope>, List<IdentityServer4.Models.ApiScope>>(scopes);
return await GetCacheItemsAsync(
ApiScopeCache,
scopeNames,
async keys => await ApiScopeRepository.GetListByNameAsync(keys, includeDetails: true),
(models, cacheKeyPrefix) => new List<IEnumerable<KeyValuePair<string, IdentityServer4.Models.ApiScope>>>
{
models.Select(x => new KeyValuePair<string, IdentityServer4.Models.ApiScope>(AddCachePrefix(x.Name, cacheKeyPrefix), x))
});
}
/// <summary>
@ -52,8 +91,16 @@ namespace Volo.Abp.IdentityServer
/// </summary>
public virtual async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
{
var resources = await ApiResourceRepository.GetListByScopesAsync(scopeNames.ToArray(), includeDetails: true);
return ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiResources.ApiResource>, List<IdentityServer4.Models.ApiResource>>(resources);
return await GetCacheItemsAsync<ApiResource, IdentityServer4.Models.ApiResource>(
ApiResourceCache,
scopeNames,
async keys => await ApiResourceRepository.GetListByScopesAsync(keys, includeDetails: true),
(models, cacheKeyPrefix) =>
{
return models
.Select(model => model.Scopes.Select(scope => new KeyValuePair<string, IdentityServer4.Models.ApiResource>(AddCachePrefix(scope, cacheKeyPrefix), model)).ToList())
.Where(scopes => scopes.Any()).Cast<IEnumerable<KeyValuePair<string, IdentityServer4.Models.ApiResource>>>().ToList();
}, ApiResourceScopeNameCacheKeyPrefix);
}
/// <summary>
@ -61,8 +108,14 @@ namespace Volo.Abp.IdentityServer
/// </summary>
public virtual async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
{
var resources = await ApiResourceRepository.FindByNameAsync(apiResourceNames.ToArray(), includeDetails: true);
return ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiResources.ApiResource>, List<IdentityServer4.Models.ApiResource>>(resources);
return await GetCacheItemsAsync(
ApiResourceCache,
apiResourceNames,
async keys => await ApiResourceRepository.FindByNameAsync(keys, includeDetails: true),
(models, cacheKeyPrefix) => new List<IEnumerable<KeyValuePair<string, IdentityServer4.Models.ApiResource>>>
{
models.Select(x => new KeyValuePair<string, IdentityServer4.Models.ApiResource>(AddCachePrefix(x.Name, cacheKeyPrefix), x))
}, ApiResourceNameCacheKeyPrefix);
}
/// <summary>
@ -70,14 +123,68 @@ namespace Volo.Abp.IdentityServer
/// </summary>
public virtual async Task<IdentityServer4.Models.Resources> GetAllResourcesAsync()
{
var identityResources = await IdentityResourceRepository.GetListAsync(includeDetails: true);
var apiResources = await ApiResourceRepository.GetListAsync(includeDetails: true);
var apiScopes = await ApiScopeRepository.GetListAsync(includeDetails: true);
return new Resources(
ObjectMapper.Map<List<Volo.Abp.IdentityServer.IdentityResources.IdentityResource>, List<IdentityServer4.Models.IdentityResource>>(identityResources),
ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiResources.ApiResource>, List<IdentityServer4.Models.ApiResource>>(apiResources),
ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiScopes.ApiScope>, List<IdentityServer4.Models.ApiScope>>(apiScopes));
return await ResourcesCache.GetOrAddAsync(AllResourcesKey, async () =>
{
var identityResources = await IdentityResourceRepository.GetListAsync(includeDetails: true);
var apiResources = await ApiResourceRepository.GetListAsync(includeDetails: true);
var apiScopes = await ApiScopeRepository.GetListAsync(includeDetails: true);
return new Resources(
ObjectMapper.Map<List<Volo.Abp.IdentityServer.IdentityResources.IdentityResource>, List<IdentityServer4.Models.IdentityResource>>(identityResources),
ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiResources.ApiResource>, List<IdentityServer4.Models.ApiResource>>(apiResources),
ObjectMapper.Map<List<Volo.Abp.IdentityServer.ApiScopes.ApiScope>, List<IdentityServer4.Models.ApiScope>>(apiScopes));
}, () => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = Options.Caching.ClientStoreExpiration
});
}
protected virtual async Task<IEnumerable<TModel>> GetCacheItemsAsync<TEntity, TModel>(
IDistributedCache<TModel> cache,
IEnumerable<string> keys,
Func<string[], Task<List<TEntity>>> entityFactory,
Func<List<TModel>, string, List<IEnumerable<KeyValuePair<string, TModel>>>> cacheItemsFactory,
string cacheKeyPrefix = null)
where TModel : class
{
var cacheItems = await cache.GetManyAsync(AddCachePrefix(keys, cacheKeyPrefix));
if (cacheItems.All(x => x.Value != null))
{
return cacheItems.Select(x => x.Value);
}
var otherKeys = RemoveCachePrefix(cacheItems.Where(x => x.Value == null).Select(x => x.Key), cacheKeyPrefix).ToArray();
var otherModels = ObjectMapper.Map<List<TEntity>, List<TModel>>(await entityFactory(otherKeys));
var otherCacheItems = cacheItemsFactory(otherModels, cacheKeyPrefix).ToList();
foreach (var item in otherCacheItems)
{
await cache.SetManyAsync(item, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = Options.Caching.ClientStoreExpiration
});
}
return cacheItems.Where(x => x.Value != null).Select(x => x.Value).Concat(otherModels);
}
protected virtual IEnumerable<string> AddCachePrefix(IEnumerable<string> keys, string prefix)
{
return prefix == null ? keys : keys.Select(x => AddCachePrefix(x, prefix));
}
protected virtual string AddCachePrefix(string key, string prefix)
{
return prefix == null ? key : prefix + key;
}
protected virtual IEnumerable<string> RemoveCachePrefix(IEnumerable<string> keys, string prefix)
{
return prefix == null ? keys : keys.Select(x => RemoveCachePrefix(x, prefix));
}
protected virtual string RemoveCachePrefix(string key, string prefix)
{
return prefix == null ? key : key.RemovePreFix(prefix);
}
}
}

@ -0,0 +1,138 @@
using System.Threading.Tasks;
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Stores;
using Shouldly;
using Volo.Abp.Caching;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.IdentityResources;
using Xunit;
using ApiResource = IdentityServer4.Models.ApiResource;
using ApiScope = IdentityServer4.Models.ApiScope;
using Client = IdentityServer4.Models.Client;
using IdentityResource = IdentityServer4.Models.IdentityResource;
namespace Volo.Abp.IdentityServer.Cache
{
public class IdentityServerCacheItemInvalidator_Tests : AbpIdentityServerTestBase
{
private readonly IClientStore _clientStore;
private readonly IResourceStore _resourceStore;
private readonly IClientRepository _clientRepository;
private readonly IIdentityResourceRepository _identityResourceRepository;
private readonly IApiResourceRepository _apiResourceRepository;
private readonly IApiScopeRepository _apiScopeRepository;
private readonly IDistributedCache<Client> _clientCache;
private readonly IDistributedCache<IdentityResource> _identityResourceCache;
private readonly IDistributedCache<ApiResource>_apiResourceCache;
private readonly IDistributedCache<ApiScope> _apiScopeCache;
private readonly IDistributedCache<Resources> _resourceCache;
private readonly AbpIdentityServerTestData _testData;
public IdentityServerCacheItemInvalidator_Tests()
{
_clientStore = GetRequiredService<IClientStore>();
_resourceStore = GetRequiredService<IResourceStore>();
_clientRepository = GetRequiredService<IClientRepository>();
_identityResourceRepository = GetRequiredService<IIdentityResourceRepository>();
_apiResourceRepository = GetRequiredService<IApiResourceRepository>();
_apiScopeRepository = GetRequiredService<IApiScopeRepository>();
_clientCache = GetRequiredService<IDistributedCache<Client>>();
_identityResourceCache = GetRequiredService<IDistributedCache<IdentityResource>>();
_apiResourceCache = GetRequiredService<IDistributedCache<ApiResource>>();
_apiScopeCache = GetRequiredService<IDistributedCache<ApiScope>>();
_resourceCache = GetRequiredService<IDistributedCache<Resources>>();
_testData = GetRequiredService<AbpIdentityServerTestData>();
}
[Fact]
public async Task Models_Should_Cached_And_Invalidator_When_Its_Changed()
{
//client
var clientId = "ClientId1";
(await _clientCache.GetAsync(clientId)).ShouldBeNull();
var client = await _clientStore.FindClientByIdAsync(clientId);
client.ShouldNotBeNull();
var clientCacheItem = await _clientCache.GetAsync(clientId);
clientCacheItem.ShouldNotBeNull();
await _clientRepository.DeleteAsync(_testData.Client1Id);
(await _clientCache.GetAsync(clientId)).ShouldBeNull();
//Api Resource
var newApiResource1 = "NewApiResource1";
var newApiResource2 = "NewApiResource2";
var testApiResourceName1 = "Test-ApiResource-Name-1";
var testApiResourceApiScopeName1 = "Test-ApiResource-ApiScope-Name-1";
var newApiResources = new[] {newApiResource1, newApiResource2};
//FindApiResourcesByNameAsync
(await _apiResourceCache.GetAsync(newApiResource1)).ShouldBeNull();
(await _apiResourceCache.GetAsync(newApiResource2)).ShouldBeNull();
await _resourceStore.FindApiResourcesByNameAsync(newApiResources);
(await _apiResourceCache.GetAsync(ResourceStore.ApiResourceNameCacheKeyPrefix + newApiResource1)).ShouldNotBeNull();
(await _apiResourceCache.GetAsync(ResourceStore.ApiResourceNameCacheKeyPrefix + newApiResource2)).ShouldNotBeNull();
var apiResource1 = await _apiResourceRepository.FindByNameAsync(newApiResource1);
await _apiResourceRepository.DeleteAsync(apiResource1);
(await _apiResourceCache.GetAsync(newApiResource1)).ShouldBeNull();
var apiResource2 = await _apiResourceRepository.FindByNameAsync(newApiResource2);
await _apiResourceRepository.DeleteAsync(apiResource2);
(await _apiResourceCache.GetAsync(newApiResource2)).ShouldBeNull();
//FindApiResourcesByScopeNameAsync
(await _apiResourceCache.GetAsync(ResourceStore.ApiResourceScopeNameCacheKeyPrefix + testApiResourceApiScopeName1)).ShouldBeNull();
await _resourceStore.FindApiResourcesByScopeNameAsync(new []{ testApiResourceApiScopeName1 });
(await _apiResourceCache.GetAsync(ResourceStore.ApiResourceScopeNameCacheKeyPrefix + testApiResourceApiScopeName1)).ShouldNotBeNull();
var testApiResource1 = await _apiResourceRepository.FindByNameAsync(testApiResourceName1);
await _apiResourceRepository.DeleteAsync(testApiResource1);
(await _apiResourceCache.GetAsync(ResourceStore.ApiResourceScopeNameCacheKeyPrefix + testApiResourceApiScopeName1)).ShouldBeNull();
//Identity Resource
var testIdentityResourceName = "Test-Identity-Resource-Name-1";
var testIdentityResourceNames = new[] {testIdentityResourceName};
(await _identityResourceCache.GetAsync(testIdentityResourceName)).ShouldBeNull();
await _resourceStore.FindIdentityResourcesByScopeNameAsync(testIdentityResourceNames);
(await _identityResourceCache.GetAsync(testIdentityResourceName)).ShouldNotBeNull();
var testIdentityResource = await _identityResourceRepository.FindByNameAsync(testIdentityResourceName);
await _identityResourceRepository.DeleteAsync(testIdentityResource);
(await _identityResourceCache.GetAsync(testIdentityResourceName)).ShouldBeNull();
//Api Scope
var testApiScopeName = "Test-ApiScope-Name-1";
var testApiScopeNames = new[] {testApiScopeName};
(await _apiScopeCache.GetAsync(testApiScopeName)).ShouldBeNull();
await _resourceStore.FindApiScopesByNameAsync(testApiScopeNames);
(await _apiScopeCache.GetAsync(testApiScopeName)).ShouldNotBeNull();
var testApiScope = await _apiScopeRepository.GetByNameAsync(testApiScopeName);
await _apiScopeRepository.DeleteAsync(testApiScope);
(await _apiScopeCache.GetAsync(testApiScopeName)).ShouldBeNull();
//Resources
(await _resourceCache.GetAsync(ResourceStore.AllResourcesKey)).ShouldBeNull();
await _resourceStore.GetAllResourcesAsync();
(await _resourceCache.GetAsync(ResourceStore.AllResourcesKey)).ShouldNotBeNull();
await _identityResourceRepository.DeleteAsync(_testData.IdentityResource1Id);
(await _resourceCache.GetAsync(ResourceStore.AllResourcesKey)).ShouldBeNull();
}
}
}

@ -0,0 +1,79 @@
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Stores;
using Shouldly;
using Volo.Abp.IdentityServer.ApiResources;
using Xunit;
namespace Volo.Abp.IdentityServer
{
public class ResourceStore_Cache_Tests : AbpIdentityServerDomainTestBase
{
private readonly IResourceStore _resourceStore;
public ResourceStore_Cache_Tests()
{
_resourceStore = GetRequiredService<IResourceStore>();
}
[Fact]
public async Task FindIdentityResourcesByScopeNameAsync()
{
var identityResources = (await _resourceStore.FindIdentityResourcesByScopeNameAsync(new[] {"Test-Identity-Resource-Name-1"})).ToList();
identityResources.ShouldNotBeEmpty();
identityResources.Count.ShouldBe(1);
identityResources.First().Name.ShouldBe("Test-Identity-Resource-Name-1");
var identityResources2 = (await _resourceStore.FindIdentityResourcesByScopeNameAsync(new[] {"Test-Identity-Resource-Name-1", "NewIdentityResource1"})).ToList();
identityResources2.ShouldNotBeEmpty();
identityResources2.Count.ShouldBe(2);
identityResources2.ShouldContain(x => x.Name == "NewIdentityResource1");
identityResources2.ShouldContain(x => x.Name == identityResources.First().Name);
}
[Fact]
public async Task FindApiScopesByNameAsync()
{
var apiScopes1 = (await _resourceStore.FindApiScopesByNameAsync(new[] {"Test-ApiScope-Name-1"})).ToList();
apiScopes1.ShouldNotBeEmpty();
apiScopes1.Count.ShouldBe(1);
apiScopes1.First().Name.ShouldBe("Test-ApiScope-Name-1");
var apiScopes2 = (await _resourceStore.FindApiScopesByNameAsync(new[] {"Test-ApiScope-Name-1", "Test-ApiScope-Name-2"})).ToList();
apiScopes2.ShouldNotBeEmpty();
apiScopes2.Count.ShouldBe(2);
apiScopes2.ShouldContain(x => x.Name == "Test-ApiScope-Name-1");
apiScopes2.ShouldContain(x => x.Name == apiScopes1.First().Name);
}
[Fact]
public async Task FindApiResourcesByScopeNameAsync()
{
var apiResources1 = (await _resourceStore.FindApiResourcesByScopeNameAsync(new[] {"Test-ApiResource-ApiScope-Name-1"})).ToList();
apiResources1.ShouldNotBeEmpty();
apiResources1.Count.ShouldBe(1);
apiResources1.First().Name.ShouldBe("Test-ApiResource-Name-1");
var apiResources2 = (await _resourceStore.FindApiResourcesByScopeNameAsync(new[] {"Test-ApiResource-ApiScope-Name-1", nameof(ApiResourceScope.Scope)})).ToList();
apiResources2.ShouldNotBeEmpty();
apiResources2.Count.ShouldBe(2);
apiResources2.ShouldContain(x => x.Name == "Test-ApiResource-Name-1");
apiResources2.ShouldContain(x => x.Name == apiResources1.First().Name);
}
[Fact]
public async Task FindApiResourcesByNameAsync()
{
var apiResources1 = (await _resourceStore.FindApiResourcesByNameAsync(new[] {"Test-ApiResource-Name-1"})).ToList();
apiResources1.ShouldNotBeEmpty();
apiResources1.Count.ShouldBe(1);
apiResources1.First().Name.ShouldBe("Test-ApiResource-Name-1");
var apiResources2 = (await _resourceStore.FindApiResourcesByNameAsync(new[] {"Test-ApiResource-Name-1", "NewApiResource1"})).ToList();
apiResources2.ShouldNotBeEmpty();
apiResources2.Count.ShouldBe(2);
apiResources2.ShouldContain(x => x.Name == "NewApiResource1");
apiResources2.ShouldContain(x => x.Name == apiResources1.First().Name);
}
}
}

@ -75,6 +75,9 @@ namespace Volo.Abp.IdentityServer
apiScope.AddUserClaim("Test-ApiScope-Claim-Type-1");
await _apiScopeRepository.InsertAsync(apiScope);
var apiScope2 = new ApiScope(_guidGenerator.Create(), "Test-ApiScope-Name-2");
await _apiScopeRepository.InsertAsync(apiScope2);
}
private async Task AddApiResources()

Loading…
Cancel
Save