【问题标题】:How do you use HttpClient dependency injection with IdentityServer4?您如何将 HttpClient 依赖注入与 IdentityServer4 一起使用?
【发布时间】:2020-01-20 23:07:34
【问题描述】:

我有以下 IResourceOwnerPasswordValidator 的实现:

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private HttpClient HttpClient { get; set; }

    public ResourceOwnerPasswordValidator(HttpClient httpClient)
    {
        this.HttpClient = httpClient;
    }
}

我在 Startup.cs 的 ConfigureServices 中有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    var identityServerBuilder = services.AddIdentityServer();

    identityServerBuilder.Services.AddHttpClient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

    identityServerBuilder
        .AddInMemoryIdentityResources(ConfigurationData.IdentityResources)
        .AddInMemoryApiResources(ConfigurationData.ApiResources)
        .AddInMemoryClients(ConfigurationData.Clients)
        .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
        .AddProfileService<ProfileService>();

    // not recommended for production - you need to store your key material somewhere secure
    identityServerBuilder.AddDeveloperSigningCredential();
}

我已经尝试了几种不同的替代方法来注册 HttpClient 没有任何运气:

identityServerBuilder.Services.AddHttpClient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

services.AddHttpClient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

services.AddHttpClient<ResourceOwnerPasswordValidator>();

我总是收到以下错误:

在尝试激活“ResourceOwnerPasswordValidator”时无法解析“System.Net.Http.HttpClient”类型的服务

如果我自己在 ResourceOwnerPasswordValidator 类中实例化 HttpClient 一切正常,但我读过这样做是不好的做法,我想弄清楚为什么依赖注入不起作用。我已经能够在其他项目中使用类型化的 HttpClient 依赖注入,没有任何问题。

如果有帮助,here is the source IdentityServer4 扩展方法。

任何帮助将不胜感激。

【问题讨论】:

  • 仅仅阅读一些不好的做法是不够的。要将某事标记为“不良做法”,您必须确定优点和缺点,并确定优点是否大于缺点。你不能简单地给某事贴上“不好的做法”的标签,因为有人在不理解原因的情况下这么说;沿着这条路走下去就是疯狂的货物崇拜。
  • @RobertHarvey 这是微软在其文档中推荐的方法。这是我查找的内容,因为我知道手动实例化 HttpClient 会导致几年前另一个 .NET 应用程序中的性能问题。 docs.microsoft.com/en-us/aspnet/core/fundamentals/… 无论如何,即使我自己简单地创建一个新实例是一个可行的解决方案,我仍然很想知道为什么推荐的方法不起作用。
  • 那篇文章讨论了使用IHttpClientFactory 创建您的HttpClient 实例。它只是顺便提到了依赖注入,只是说你可以做到,而不是你应该。

标签: c# asp.net-core dependency-injection identityserver4


【解决方案1】:
identityServerBuilder.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();

这将执行以下操作under the hood

builder.Services.AddTransient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

所以这实际上相当于直接调用:

services.AddTransient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

但是,此调用与 AddHttpClient 方法的作用相冲突,因为该方法不只是直接注册服务,而是注册 a factory,这将首先通过 HttpClientFactory 解析 HttpClient

所以基本上,通过调用AddResourceOwnerValidator&lt;&gt;()之后,您将覆盖 HTTP 客户端注册。

如果您移动注册,它应该可以工作,但是由于 AddResourceOwnerValidator&lt;&gt;() 除了注册该接口类型之外实际上并没有做任何特殊的事情,您可以完全不使用它:

// register the IResourceOwnerPasswordValidator as an HTTP client
services.AddHttpClient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

// do not register anther IResourceOwnerPasswordValidator
services.AddIdentityServer()
    .AddInMemoryIdentityResources(ConfigurationData.IdentityResources)
    .AddInMemoryApiResources(ConfigurationData.ApiResources)
    .AddInMemoryClients(ConfigurationData.Clients)
    .AddProfileService<ProfileService>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    相关资源
    最近更新 更多