【问题标题】:Use HttpClient within middleware pipeline?在中间件管道中使用 HttpClient?
【发布时间】:2018-04-19 00:49:12
【问题描述】:

我正在使用 ASP.NET Core 开发一个 API 项目,我必须使用公司拥有的自定义 OAuth 服务(也是 ASP.NET Core)。应该在对 API 发出的每个请求上调用该服务,以验证用户是否有权使用该资源,所以我想我可以在 API 上创建一个中间件来处理对 OAuth 服务的请求。

我的问题是我还在学习 C# 和 ASP.NET Core,我不确定这是否可以完成。我做了一些谷歌搜索,但我找不到在中间件上完成 HttpClient 调用的示例。我想知道是否有人可以提示我是否走在正确的道路上,或者这是否被认为是不好的做法,以及有更好的方法来实现它。

【问题讨论】:

  • 这似乎有点笨拙。大多数 oauth 流程都承认,在一段时间内使用可刷新的授权令牌而不是在每个请求上都使用“请求验证服务”是可以接受的。在每个请求中“重新验证”用户真的是你需要的吗?
  • 您好,感谢您的快速评论。我确实注意到它有点笨拙,但他们希望,至少目前,要使用该服务。我建议公司也改用这种工作流程,但我希望如果可能的话,我可以使用我现在拥有的东西。
  • 你应该没问题,只要你小心重用一个 HttpClient 实例。
  • 看起来应该使用身份验证方案。不要认为你需要中间件
  • HttpClientHttpContext ?

标签: c# authentication asp.net-core httpclient middleware


【解决方案1】:

您需要编写自定义身份验证方案并将其添加到ConfigureServices 中的身份验证中

基本上你需要实现AuthenticationHandler并注入HttpClient

public class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{


    public const string SchemeName = "CustomSchemeName";
    private readonly HttpClient _httpclient;

    public LocalAccessTokenValidationHandler(IOptionsMonitor<LocalAccessTokenValidationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock,  HttpClient httpclient)
        : base(options, logger, encoder, clock)
    {
        _httpclient= httpclient;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // use _httpclient here and authenticate request and return AuthenticateResult
    }

然后将其添加到您的身份验证服务中

services.AddAuthentication(CustomAuthHandler.SchemeName) // setting CustomAuthHandler as the default
        .AddScheme<CustomAuthOptions, CustomAuthHandler>(CustomAuthHandler.SchemeName); 

HttpClient注册为单身人士:

services.AddSingleton(new HttpClient());

然后你需要确保你所有的控制器都被标记为[Authorize]

查看blog 了解更多详情。 查看filters,了解如何将所有控制器标记为全局授权。这样您就不必用[Authorize] 属性标记每个控制器。

【讨论】:

  • 我不明白为什么HttpClient 需要注入到服务器端应用程序中
  • 最好有一个HttpClient 实例并在任何地方使用它。 Microsoft 还在 ASP.NET Core 2.1 中添加了名为 HttpClientFactory 的新类。你可以在这里查看,stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore
  • 由于 2.1 仍处于预览阶段,我认为到目前为止,制作像 services.AddSingleton(new HttpClient { BaseAddress = new Uri("http://google.com") }); 这样的单例应该更安全
  • @NevilleNazerane 你编辑了我的答案,你的意思是[Authorize] 而不是[Authenticated]
  • @Kahbazi:嗯,这更好,但是没有什么可以阻止某些代码稍后设置它,或者再次设置默认标头。然后,这会影响整个应用程序中的所有其他 HttpClient 使用,并可能导致您发出的其他请求突然无缘无故地失败。如果你不想走完整的工厂路线,你可以简单地创建一个或多个“访问器”类,每个类都创建一个HttpClient 的实例,然后将它们限定为单例。然后,您可以为每种情况注入适当的“访问器”。不像工厂那么优雅,但可以完成工作。
猜你喜欢
  • 2020-09-26
  • 1970-01-01
  • 2023-03-27
  • 2011-02-15
  • 2020-02-15
  • 2021-09-24
  • 1970-01-01
  • 2019-07-04
  • 2015-08-25
相关资源
最近更新 更多