.net Core - 使用AWS Load Balancer和Elastic Beanstalk的HTTPS不起作用

时间:2017-10-12 04:54:25

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

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

我在AWS中的设置是一个Elastic Beanstalk应用程序,一个运行MS SQL的RDS数据库,我添加了一个Load Balancer来转发HTTPS请求,我有一个正确分配给Load Balancer的SSL证书。从我可以告诉我的应用程序正在运行,事实上,实体框架已启动并在我的RDS实例中正确构建了我的数据库。我无法通过互联网访问该网站。

我尝试过以不同的方式设置听众。如果我像这样设置它们,它只是永远重定向: Redirect Forever

如果我这样设置它们,它只会超时: enter image description here

我有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等博客的代码解决方案,但这些解决方案也无效。根据我的阅读,Load Balancer最终处理HTTPS请求,然后将HTTP请求转发给我的应用程序。但我不知道如何正确处理,仍然强制执行HTTPS,并将HTTP重定向到HTTPS。

这似乎是没有一堆设置就可以开箱即用的东西。如果不是,我认为现在很多其他人都会遇到这个问题,并且在互联网上有关于它的信息。我错过了一些小事吗?因为我完全以我的智慧结束了这件事。

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

5 个答案:

答案 0 :(得分:11)

所以我终于解决了这个问题。首先,必须将Load Balancer设置为将HTTPS 443转发到HTTP 80,如下所示: enter image description here

然后,我在问题中概述的所有代码都需要删除(或者不在AWS环境中运行)。我最初忘了删除services.Configure<MvcOptions>(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);
    ... 
}

毕竟它终于奏效了!

答案 1 :(得分:3)

根据this AWS docs,您必须仅在X-Forwarded-Proto(而不是http)时分析https标题和带有重定向的回复。

来自RedirectToHttpsRule包的当前Microsoft.AspNetCore.Rewrite not analyze this。您需要实现自己的IRule

答案 2 :(得分:0)

app.UseForwardedHeaders()似乎与AWS Load Balancers有问题,除非您先清除已知的网络和代理。

不要忘记首先安装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;
    }

答案 3 :(得分:0)

您需要接受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();
 ...
}

答案 4 :(得分:0)

我面临着同样的问题。我最终通过更改web.config文件解决了此问题。

下面的确切代码对我有用。我关注this link。如果未安装URL重写模块,则必须在实例上安装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>