【问题标题】:Does Kestrel need UseHttps when making a request to an HTTPS endpoit?向 HTTPS 端点发出请求时,Kestrel 是否需要使用 Https?
【发布时间】:2019-11-20 05:48:31
【问题描述】:

我在反向代理 (Nginx) 后面配置了 Kestrel。我正在尝试使用一个端点(即 HTTPS)并且我不断收到:

Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException:请求行无效。

在互联网上搜索了一段时间后,我看到有人说这是因为我从 HTTPS 端点访问 HTTP 端点,但就我而言,我从 HTTP 访问 HTTPS 端点并且不太确定如何解决这个问题。我正在执行this 之后的请求,并进行了一些修改:

var json = JsonConvert.SerializeObject(new{ FieldA = "A", FieldB = "B" });
var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/some-endpoint")
{
    Content = new StringContent(json, Encoding.UTF8)
};
request.Content.Headers.Add(HeaderNames.ContentType, MediaTypeNames.Application.Json);

var client = httpClientFactory.CreateClient("my-client");
var response = await client.SendAsync(request);

var myResp = await response.Content.ReadAsAsync<MyResponse>();

我正在通过以下方式注册IHttpClientFactory

services.AddHttpClient("my-client", (sp, c) =>
{
    var opts = sp.GetRequiredService<IOptions<MyOptions>>().Value;
    var uriB = new UriBuilder
    {
        Host = opts.Host,
        Port = opts.Port,
        Scheme = Uri.UriSchemeHttps
    };
    c.BaseAddress = uriB.Uri;
});

我不希望仅仅为此将 Kestrel 配置为UseHttps,因为我让 Nginx 将来自外部世界的 HTTPS 处理到我的应用程序中。我可以做些什么来代替那个(假设可以解决错误)?

更新:我的目标是 .Net Core 2.1 版本,并通过以下方式使用转发的标头中间件:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost
});

这也是我在Startup.Configure 方法中使用的第一个中间件。我的 Nginx 位置配置为:

location /api {
    proxy_pass         http://localhost:5000;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection keep-alive;
    proxy_set_header   Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
}

【问题讨论】:

  • ASP.NET Core 的哪个版本?你打电话给UseForwardedHeaders吗? docs.microsoft.com/en-us/aspnet/core/host-and-deploy/… iirc 在某些版本中存在一些约束,UseForwardedHeader 没有被 UseIISIntegration 隐式调用(在 Linux 上没有调用)。只要您使用带有正确标头名称的UseForwardedHeaders 并且您的反向代理发送这些 ASP.nET Core 就会将其识别为 Https 而不会执行 https 重定向。还要避免使用UseHttpsRedirection
  • @Tseng 我编辑了我的问题。我看到我正在使用app.UseHttpsRedirection(),我将删除它并重试。感谢您的回复。

标签: c# asp.net-core https


【解决方案1】:

问题在于我构建请求的方式。我遵循了@Tseng 的建议,但一直收到错误消息,我什至明确更改了转发的标头名称以匹配我的 Nginx 配置中设置的名称(以防万一),但没有成功。这就是我让它工作的方式:

var json = JsonConvert.SerializeObject(new{ FieldA = "A", FieldB = "B" });
var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/some-endpoint")
{
    Content = new StringContent(json, Encoding.UTF8)
};
//Changed this line. I think the previous line was the problem 'cause 
// I saw a header duplication error in the stack trace referring to
// the content type header, so overriding the header may have 
// made the error gone
request.Content.Headers.ContentType = new MediaTypeHeaderValue(MediaTypeNames.Application.Json);

var client = httpClientFactory.CreateClient("my-client");
var response = await client.SendAsync(request);

var myResp = await response.Content.ReadAsAsync<MyResponse>();

并将我的IHttpClientFactory 配置更新为:

services.AddHttpClient("my-client", (sp, c) =>
{
    var opts = sp.GetRequiredService<IOptions<MyOptions>>().Value;
    var uriB = new UriBuilder
    {
        Host = opts.Host,
        Port = opts.Port,
        Scheme = Uri.UriSchemeHttps
    };
    c.BaseAddress = uriB.Uri;
    // Added this line
    c.DefaultRequestHeaders.Add(HeaderNames.Accept, MediaTypeNames.Application.Json);
});

This 帖子帮助我进行了更改。希望这对将来的人有所帮助。

【讨论】:

    猜你喜欢
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 2018-11-25
    • 2012-08-26
    • 2017-10-26
    相关资源
    最近更新 更多