Browse Source

Cache a `scope` with multiple `ApiResource`.

Fix #13982
pull/14006/head
maliming 4 years ago
parent
commit
96f1446b9e
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 29
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ResourceStore.cs
  2. 6
      modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/ResourceStore_Cache_Tests.cs
  3. 1
      modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs

29
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ResourceStore.cs

@ -31,6 +31,7 @@ public class ResourceStore : IResourceStore
protected IDistributedCache<IdentityServer4.Models.IdentityResource> IdentityResourceCache { get; }
protected IDistributedCache<IdentityServer4.Models.ApiScope> ApiScopeCache { get; }
protected IDistributedCache<IdentityServer4.Models.ApiResource> ApiResourceCache { get; }
protected IDistributedCache<IEnumerable<IdentityServer4.Models.ApiResource>> ApiResourcesCache { get; }
protected IDistributedCache<IdentityServer4.Models.Resources> ResourcesCache { get; }
protected IdentityServerOptions Options { get; }
@ -42,6 +43,7 @@ public class ResourceStore : IResourceStore
IDistributedCache<IdentityServer4.Models.IdentityResource> identityResourceCache,
IDistributedCache<IdentityServer4.Models.ApiScope> apiScopeCache,
IDistributedCache<IdentityServer4.Models.ApiResource> apiResourceCache,
IDistributedCache<IEnumerable<IdentityServer4.Models.ApiResource>> apiResourcesCache,
IDistributedCache<Resources> resourcesCache,
IOptions<IdentityServerOptions> options)
{
@ -52,6 +54,7 @@ public class ResourceStore : IResourceStore
IdentityResourceCache = identityResourceCache;
ApiScopeCache = apiScopeCache;
ApiResourceCache = apiResourceCache;
ApiResourcesCache = apiResourcesCache;
ResourcesCache = resourcesCache;
Options = options.Value;
}
@ -91,16 +94,22 @@ public class ResourceStore : IResourceStore
/// </summary>
public virtual async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
{
return (await GetCacheItemsAsync(
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)).DistinctBy(x => x.Name);
var cacheItems = await ApiResourcesCache.GetManyAsync(AddCachePrefix(scopeNames, ApiResourceScopeNameCacheKeyPrefix));
if (cacheItems.All(x => x.Value != null))
{
return cacheItems.SelectMany(x => x.Value).DistinctBy(x => x.Name);
}
var otherKeys = RemoveCachePrefix(cacheItems.Where(x => x.Value == null).Select(x => x.Key), ApiResourceScopeNameCacheKeyPrefix).ToArray();
var otherModels = ObjectMapper.Map<List<ApiResource>, List<IdentityServer4.Models.ApiResource>>(await ApiResourceRepository.GetListByScopesAsync(otherKeys, includeDetails: true));
var otherCacheItems = otherKeys.Select(otherKey => new KeyValuePair<string, IEnumerable<IdentityServer4.Models.ApiResource>>(AddCachePrefix(otherKey, ApiResourceScopeNameCacheKeyPrefix), otherModels)).ToList();
await ApiResourcesCache.SetManyAsync(otherCacheItems, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = Options.Caching.ClientStoreExpiration
});
return cacheItems.Where(x => x.Value != null).SelectMany(x => x.Value).Concat(otherModels).DistinctBy(x => x.Name);
}
/// <summary>

6
modules/identityserver/test/Volo.Abp.IdentityServer.Domain.Tests/Volo/Abp/IdentityServer/ResourceStore_Cache_Tests.cs

@ -51,14 +51,14 @@ public class ResourceStore_Cache_Tests : AbpIdentityServerDomainTestBase
{
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");
apiResources1.Count.ShouldBe(2);
apiResources1.ShouldContain(x => x.Name == "Test-ApiResource-Name-1");
var apiResources2 = (await _resourceStore.FindApiResourcesByScopeNameAsync(new[] { "Test-ApiResource-ApiScope-Name-1", "Test-ApiResource-ApiScope-Name-2", 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);
apiResources2.ShouldContain(x => x.Name == "NewApiResource1");
}
[Fact]

1
modules/identityserver/test/Volo.Abp.IdentityServer.TestBase/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs

@ -87,6 +87,7 @@ public class AbpIdentityServerTestDataBuilder : ITransientDependency
apiResource.DisplayName = nameof(apiResource.DisplayName);
apiResource.AddScope(nameof(ApiResourceScope.Scope));
apiResource.AddScope("Test-ApiResource-ApiScope-Name-1");
apiResource.AddUserClaim(nameof(ApiResourceClaim.Type));
apiResource.AddSecret(nameof(ApiResourceSecret.Value));

Loading…
Cancel
Save