在 Heroku 上为仅侦听 https 的服务使用哪个环境变量

Ame*_*liu 3 c# heroku asp.net-core

我正在使用将部署在 Heroku 上的 AspNet 核心设置一个仅限 https 的 Web API 服务。部署是通过 docker 完成的,所以我配置了一个 Dockerfile。但是,每当我部署到 Heroku 时,都会收到与 https 端口绑定相关的错误。我想知道 Heroku 是否为 https 提供了一个特殊的 env 变量,服务可以在其中绑定以指定服务应该侦听的 https 端口。

AspNet 核心提供 2 个环境变量ASPNETCORE_HTTPS_PORT=5001ASPNETCORE_URLS=https://*:5001其中可以指定服务应侦听的 https 端口。

但是由于 Heroku 不允许 Web 进程手动指定它应该侦听的端口,因此它们提供了一个 Web 应用程序可以绑定到的 PORT 环境变量。

我试过使用ASPNETCORE_HTTPS_PORT=$PORTand ASPNETCORE_URLS=https://*:$PORT,但出现以下错误:

crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.Net.Sockets.SocketException (13): Permission denied at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName) 
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
Run Code Online (Sandbox Code Playgroud)

Ame*_*liu 5

因此,在(广泛地)阅读 Heroku 的文档后,我能够解决该问题。以下是与此问题相关的主要发现:

  1. Heroku 使用一个负载均衡器来代理它的所有请求。
  2. Heroku 终止来自您的应用程序的任何 SSL 通信,因此所有请求都通过 http 转发到您的应用程序;您客户的 https 请求是通过 http 代理的。
  3. 由于请求是代理的,Heroku为原始请求传递转发的标头
  4. 您的应用程序只能接收请求,并且应该只侦听 PORT 环境变量。

现在我有了想法,我能够正确配置我的应用程序。

侦听 http 而不是 https: ASPNETCORE_URLS=http://*:$PORT

在 AspNet 核心中间件管道中使用 ForwardedHeaders 和 Rewriter 中间件:

var forwardedHeadersOptions = new ForwardedHeadersOptions {
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardedHeadersOptions.KnownNetworks.Clear();
forwardedHeadersOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedHeadersOptions);

var rewriteOptions = new RewriteOptions ().AddRedirectToHttps(308);
app.UseRewriter(rewriteOptions);
...
Run Code Online (Sandbox Code Playgroud)

ForwardedHHeaders 中间件将 Forwarded 标头映射到 HttpContext.Request。并且 Rewriter 中间件会将 http 请求方案重定向到 https