简体   繁体   English

使用FlurlClient的自定义HttpClientHandler不使用ClientCertificate

[英]Custom HttpClientHandler using FlurlClient doesn't use ClientCertificate

I need to add a client certificate to my web requests and tried to achieve it in this way: Stackoverflow 我需要在我的Web请求中添加客户端证书,并尝试以这种方式实现它: Stackoverflow

At the end of this answer the "FlurlClient way" is presented. 在这个答案的最后,提出了“FlurlClient方式”。 Using and configuring a FlurlClient instead of a global FlurlHttp configuration. 使用和配置FlurlClient而不是全局FlurlHttp配置。 I've tried this, but it didn't work. 我试过这个,但它没有用。

I've created a new .NET Core Console application to show you the problem: 我已经创建了一个新的.NET Core Console应用程序来向您显示问题:

static void Main(string[] args)
{
   /****** NOT WORKING *******/
   try
   {
      IFlurlClient fc1 = new FlurlClient(url)
         .ConfigureClient(c => c.HttpClientFactory = new X509HttpFactory(GetCert()));

      fc1.WithHeader("User-Agent", userAgent)
         .WithHeader("Accept-Language", locale);

      dynamic ret1 = fc1.Url.AppendPathSegments(pathSegments).GetJsonAsync()
         .GetAwaiter().GetResult();
   }
   catch
   {
      // --> Exception: 403 FORBIDDEN
   }


   /****** NOT WORKING *******/
   try
   {
      IFlurlClient fc2 = new FlurlClient(url);

      fc2.Settings.HttpClientFactory = new X509HttpFactory(GetCert());

      fc2.WithHeader("User-Agent", userAgent)
         .WithHeader("Accept-Language", locale);

      dynamic ret2 = fc2.Url.AppendPathSegments(pathSegments).GetJsonAsync()
         .GetAwaiter().GetResult();
   }
   catch
   {
      // --> Exception: 403 FORBIDDEN
   }


   /****** WORKING *******/
   FlurlHttp.Configure(c =>
   {
      c.HttpClientFactory = new X509HttpFactory(GetCert());
   });

   dynamic ret = url.AppendPathSegments(pathSegments).GetJsonAsync()
      .GetAwaiter().GetResult();
   // --> OK
}

The X509HttpFactory is copied from the linked StackOverflow answer (but using HttpClientHandler instead of WebRequestHandler ): 从链接的StackOverflow答案复制X509HttpFactory (但使用HttpClientHandler而不是WebRequestHandler ):

public class X509HttpFactory : DefaultHttpClientFactory
{
   private readonly X509Certificate2 _cert;

   public X509HttpFactory(X509Certificate2 cert)
   {
      _cert = cert;
   }

   public override HttpMessageHandler CreateMessageHandler()
   {
      var handler = new HttpClientHandler();
      handler.ClientCertificates.Add(_cert);
      return handler;
   }
}

So using the global FlurlHttp configuration is working and configuring the FlurlClient is not working. 因此,使用全局FlurlHttp配置正在工作,并且配置FlurlClient无法正常工作。 Why? 为什么?

This all comes down to the order you're calling things: 这一切都归结为你所称的顺序:

  • fc.Url returns a Url object, which is little more than a string-building thing. fc.Url返回一个Url对象,它只不过是一个字符串构建的东西。 It doesn't hold a reference back to the FlurlClient . 它不包含对FlurlClient的引用。 (This allows Flurl to exist as a URL building library independent of Flurl.Http.) (这允许Flurl作为独立于Flurl.Http的URL构建库存在。)
  • Url.AppendPathSegments returns "this" Url . Url.AppendPathSegments返回“this” Url
  • Url.GetJsonAsync is an extension method that first creates a FlurlClient , then uses it with the current Url to make the HTTP call. Url.GetJsonAsync是一种扩展方法,首先创建一个FlurlClient ,然后将其与当前的Url一起使用来进行HTTP调用。

So as you can see, you've lost your reference to fc in step 1 of that flow. 正如您所看到的,您在该流程的第1步中丢失了对fc的引用。 2 possible solutions: 2种可能的解决方

1. Build the URL first, then fluently add in the HTTP bits: 1.首先构建URL,然后流畅地添加HTTP位:

url
    .AppendPathSegments(...)
    .ConfigureClient(...)
    .WithHeaders(...)
    .GetJsonAsync();

2. OR, if you want to reuse the FlurlClient, "attach" it to the URL using WithClient: 2.或者,如果要重用FlurlClient,请使用WithClient将其“附加”到URL:

var fc = new FlurlClient()
    .ConfigureClient(...)
    .WithHeaders(...);

url
    .AppendPathSegments(...)
    .WithClient(fc)
    .GetJsonAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 Steeltoe DiscoveryHttpMessageHandler 与 FlurlClient 一起使用 - Using Steeltoe DiscoveryHttpMessageHandler with FlurlClient 将 HttpClientHandler 与 ODataClient 一起使用 - Use HttpClientHandler with ODataClient 没有 FlurlClient 的自定义 HttpClientFactory 的 IOC 注册到 Flurl - IOC registration of custom HttpClientFactory to Flurl without FlurlClient 在自定义 HttpClientHandler 中设置 allowautoredirect= false - set allowautoredirect= false in custom HttpClientHandler 为什么 HttpClientHandler 没有正确选择和使用默认代理设置? - Why isn't HttpClientHandler picking up and using default proxy settings correctly? 如何在 .NET Core 中使用 HttpClientHandler 和 HttpClientFactory - How to use HttpClientHandler with HttpClientFactory in .NET Core Httpclienthandler Webproxy 值没有改变 - Httpclienthandler Webproxy value isn't changing basicHttpBinding不使用自定义ServiceCredentials - basicHttpBinding doesn't use custom ServiceCredentials 将HttpClientHandler.AutomaticDecompression与WebApplicationFactory.CreateClient()一起使用 - Using HttpClientHandler.AutomaticDecompression with WebApplicationFactory.CreateClient() ASP.NET 带有自定义 HttpClientHandler 的核心模拟 HttpClient - ASP.NET Core mock HttpClient with custom HttpClientHandler
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM