如何使用数据库中定义的自定义api资源而不是InMemoryResource

时间:2019-02-10 05:42:10

标签: .net-core identityserver4

我们正在使用带有.net core 2.1的身份服务器4。我们的授权服务器可以很好地使用内存资源。我已经使用IResourcesStore来使用自定义资源,但是当我调用授权服务器来发出访问令牌时,我面临的问题是IReourcesStore的每个方法都被调用了两次。

我的创业公司在这里:

  private void ConfigureOpenId(IServiceCollection services)
    {
        services.AddIdentityServer(action => 
        {
            action.Caching = new CachingOptions
            {
                ResourceStoreExpiration = TimeSpan.FromSeconds(10)
            };
        }).AddSigningCredential(CertificateUtil.Load(AppEnvironment.MapToPhysicalFilePath(Configuration["Saml2:SigningCertificateFile"]), Configuration["Saml2:CertificatePassword"]))
        .AddResourceStore<ResourceStore>()
       .AddSecretValidator<CustomSecretValidator>()
       .AddClientStore<CustomClientStore>()
       .AddCustomTokenRequestValidator<CustomClientClaimsAdder>()         
       .AddInMemoryIdentityResources(OpenIdConfig.GetIdentityResources()).AddResourceStore<ResourceStore>();

        // AddCustomTokenRequestValidator<CustomAuthenticationRequestValidator>().AddCustomAuthorizeRequestValidator<CustomAuthorizeRequestValidator>()
    }

IResourceStore的实现类似于:

  public class ResourceStore : IResourceStore
{
    public ResourceStore()
    {
    }

    public Task<ApiResource> FindApiResourceAsync(string name)
    {
        var apiresource = new ApiResource();           

        return Task.FromResult(apiresource);
    }

    public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeAsync(IEnumerable<string> scopeNames)
    {
        var apiresource = new ApiResource
        {
            Name = "user",
            Scopes = new List<Scope> { new Scope("users.get") }
        };
        var list = new List<ApiResource>();
        list.Add(apiresource);
        IEnumerable<ApiResource> en = list;
        return Task.FromResult(en);
    }

    public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeAsync(IEnumerable<string> scopeNames)
    {
        var identity = new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile()
        };

        IEnumerable<IdentityResource> en = identity;
        return Task.FromResult(en);
    }

    public Task<Resources> GetAllResourcesAsync()
    {           
        var res = new Resources();          

        return Task.FromResult(res);
    }
}

在上面的方法2和3中,调用了两次。

1 个答案:

答案 0 :(得分:0)

那么,如果我没记错的话,问题在于缓存无法正常工作吗?

根据您的代码,看来您已经为资源存储实现缓存了一半。

IdentityServer.Options.Caching.ResourceStoreExpiration

  

从中加载身份和API资源配置的缓存持续时间   资源存储。

但是:

  

这些设置仅在启用了相应缓存的情况下适用   启动时的服务配置。

因此添加caching in startup应该启用它。

.AddInMemoryCaching()

然后替换此行:

.AddResourceStore<ResourceStore>()

有这行:

.AddResourceStoreCache<ResourceStore>()

更新:

我没有注意到,但是您两次添加了.AddResourceStore()。另外,添加自己的资源存储区时不需要AddInMemoryIdentityResources。

因此您的最终设置应如下所示:

services.AddIdentityServer(action => 
{
    action.Caching = new CachingOptions
    {
        ResourceStoreExpiration = TimeSpan.FromSeconds(10)
    };
})
.AddSigningCredential(CertificateUtil.Load(AppEnvironment.MapToPhysicalFilePath(Configuration["Saml2:SigningCertificateFile"]), Configuration["Saml2:CertificatePassword"]))
.AddSecretValidator<CustomSecretValidator>()
.AddClientStore<CustomClientStore>()
.AddCustomTokenRequestValidator<CustomClientClaimsAdder>()
.AddInMemoryCaching()
.AddResourceStore<ResourceStore>();