【问题标题】:.net Core - HTTPS with AWS Load Balancer and Elastic Beanstalk doesn't work.net Core - 带有 AWS 负载均衡器和 Elastic Beanstalk 的 HTTPS 不起作用
【发布时间】:2018-03-23 22:08:45
【问题描述】:

我有一个在我的本地环境中正确运行 HTTPS 的网站。当我将它上传到 AWS 时,它只会超时或永远重定向。

我在 AWS 中的设置是一个 Elastic Beanstalk 应用程序,一个运行 MS SQL 的 RDS 数据库,我添加了一个负载均衡器来转发 HTTPS 请求,并且我有一个正确分配给负载均衡器的 SSL 证书。据我所知,我的应用程序正在运行,事实上,Entity Framework 启动并在我的 RDS 实例中正确构建了我的数据库。我就是无法通过互联网访问该网站。

我尝试过以不同的方式设置监听器。如果我这样设置它们,它只会永远重定向:

如果我这样设置它们,它就会超时:

我有default HTTP/HTTPS port forwarding code in my Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // Sets all calls to require HTTPS: https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });
    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Force all HTTP requests to redirect to HTTPS: https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl
    var options = new RewriteOptions().AddRedirectToHttps();
    app.UseRewriter(options);

    ...

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

我已经为此花费了几天时间,但我无法让它发挥作用。我试过把我所有的 HTTPS 代码都拿出来,但这不起作用。我已经尝试过来自 thisthis 等博客的代码解决方案,但这也不起作用。根据我的阅读,负载均衡器最终会处理 HTTPS 请求,然后将 HTTP 请求转发到我的应用程序。但我不知道如何正确处理,仍然强制执行 HTTPS,并将 HTTP 重定向到 HTTPS。

这似乎是开箱即用的东西,无需我进行大量设置。如果不是这样,我认为现在很多其他人都会遇到这个问题,并且互联网上会有关于它的信息。我错过了一些小东西吗?因为我对此完全束手无策。

如果你能回答这个问题,你将成为我的新英雄。

【问题讨论】:

  • 你能确认一下,如果你的负载均衡器是面向互联网的吗?您可以在描述选项卡中查看此详细信息
  • 是的,负载均衡器是“面向互联网的”。

标签: amazon-web-services https asp.net-core .net-core amazon-elastic-beanstalk


【解决方案1】:

根据this AWS docs,您必须分析X-Forwarded-Proto 标头并仅在http(而不是https)时使用重定向响应。

来自Microsoft.AspNetCore.Rewrite 包的当前RedirectToHttpsRulenot analyze this。你需要实现自己的IRule

【讨论】:

  • 所以我尝试按照this blog 作为指导分析X-Forwarded-Proto 标头。我仍然无法让它工作。
  • 按照博客示例,更加勤奋地工作了。感谢您的意见和帮助。
【解决方案2】:

所以我终于解决了这个问题。首先,负载均衡器必须设置为将 HTTPS 443 转发到 HTTP 80,如下所示:

然后,我在问题中概述的所有代码都需要删除(或不在 AWS 环境中运行)。我最初忘记删除 services.Configure&lt;MvcOptions&gt;(options){} 代码行,我相信这是导致错误的原因。

然后我跟着this blog 处理 X-Forwarded-Proto 标头。我将所有代码放在一个扩展文件中:

public static class RedirectToProxiedHttpsExtensions
{
    public static RewriteOptions AddRedirectToProxiedHttps(this RewriteOptions options)
    {
        options.Rules.Add(new RedirectToProxiedHttpsRule());
        return options;
    }
}

public class RedirectToProxiedHttpsRule : IRule
{
    public virtual void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        // #1) Did this request start off as HTTP?
        string reqProtocol;
        if (request.Headers.ContainsKey("X-Forwarded-Proto"))
        {
            reqProtocol = request.Headers["X-Forwarded-Proto"][0];
        }
        else
        {
            reqProtocol = (request.IsHttps ? "https" : "http");
        }


        // #2) If so, redirect to HTTPS equivalent
        if (reqProtocol != "https")
        {
            var newUrl = new StringBuilder()
                .Append("https://").Append(request.Host)
                .Append(request.PathBase).Append(request.Path)
                .Append(request.QueryString);

            context.HttpContext.Response.Redirect(newUrl.ToString(), true);
        }
    }
}

最后,我在 Startup.cs 中调用这段代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...
    var options = new RewriteOptions()
        .AddRedirectToProxiedHttps()
        .AddRedirect("(.*)/$", "$1");  // remove trailing slash
    app.UseRewriter(options);
    ... 
}

毕竟它终于奏效了!

【讨论】:

  • 谢谢。我终于让这个工作了。我已将 HealthCheck 页面从默认 / 修改为 html 文件(即 HealthCheck.html)。
  • 这很好用。但另一个问题是,如果使用 Azure Authentication,所有请求都是通过 http 发送的,并且事后重写。我必须将带有 http 的回复 url 添加到 azure 中的应用程序列表中。有什么想法吗?
  • 不,抱歉,我不熟悉 Azure 的基础架构。祝你好运。
【解决方案3】:

app.UseForwardedHeaders() 似乎与 AWS 负载均衡器有问题,除非您先清除已知网络和代理。

不要忘记先安装 Microsoft.AspNetCore.HttpOverrides NuGet 包,否则它会静默失败。

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...
        app.UseForwardedHeaders(GetForwardedHeadersOptions());
        ...
    }

    private static ForwardedHeadersOptions GetForwardedHeadersOptions()
    {
        ForwardedHeadersOptions forwardedHeadersOptions = new ForwardedHeadersOptions()
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        };

        forwardedHeadersOptions.KnownNetworks.Clear();
        forwardedHeadersOptions.KnownProxies.Clear();

        return forwardedHeadersOptions;
    }

【讨论】:

  • 我试过这个并没有解决问题。我的解决方案确实解决了这个问题。我使用的是旧版本的 Microsoft.AspNetCore.HttpOverrides (1.1.2),会不会有问题?
  • 是的,这可以处理大多数中间件的 X-Forwarded-For 标头中的正确协议,但显然不适用于 Rewrite.AddRedirectToHttps 我最终不得不自己使用您的解决方案 :) 但我不得不将其更改为如果 X-Forwarded-Proto 标头丢失,一点点不重定向 http://。这样我的负载均衡器运行状况检查就不会被重定向到 https。
  • ArcadeRenegade 你能分享一下你为健康检查做了什么吗?
【解决方案4】:

您需要接受 XForwardedProto

在 Startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
  ...
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
    });
   ...  
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
 ...
 app.UseForwardedHeaders();
 ...
}

【讨论】:

    【解决方案5】:

    我遇到了同样的问题。我终于通过更改 web.config 文件解决了这个问题。

    下面的确切代码对我有用。我关注this link。如果没有安装 URL 重写模块,那么您必须在您的实例上安装它,否则只有这个 web.config 文件更改才会起作用。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>    
      <system.webServer>        
        <rewrite>            
          <rules>                
            <rule name="HTTPS rewrite behind AWS ELB rule" enabled="true" stopProcessing="true">
              <match url="^(.*)$" ignoreCase="false" />
              <conditions>
                <add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />                    
              </conditions>                    
              <action type="Redirect" url="https://{SERVER_NAME}{URL}" redirectType="Found" />                
            </rule>            
          </rules>        
        </rewrite>    
      </system.webServer>
    </configuration>
    

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2021-05-31
      • 2017-09-28
      • 2017-02-14
      • 2020-10-11
      • 2019-04-21
      • 2014-02-11
      • 1970-01-01
      • 2020-11-21
      相关资源
      最近更新 更多