.net Core - HTTPS with AWS Load Balancer and Elastic Beanstalk doesn't work

余生长醉 提交于 2019-12-03 12:10:25

So I finally got this fixed. First, the Load Balancer has to be set to forward HTTPS 443 to HTTP 80 like this:

Then, ALL the code I've outlined in my question needs to be deleted (or not run in the AWS environment). I forgot to remove the services.Configure<MvcOptions>(options){} lines of code initially and I believe that was what was causing the error.

Then I followed this blog to handle the X-Forwarded-Proto header. I put all the code in one extension file:

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);
        }
    }
}

Finally, I call this code in Startup.cs:

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

After all that it finally worked!

According to this AWS docs you must analyze X-Forwarded-Proto header and response with redirects only when it is http (not https).

Current RedirectToHttpsRule from Microsoft.AspNetCore.Rewrite package does not analyze this. You need to implement your own IRule.

app.UseForwardedHeaders() seems to have issues with AWS Load Balancers unless you clear the known networks and proxies first.

Don't forget to install the Microsoft.AspNetCore.HttpOverrides NuGet package first otherwise it will fail silently.

    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;
    }

You need to accept the XForwardedProto

In Startup.cs:

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

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

I was facing same issue.I finally got this fixed by changing web.config file.

Below Exact code Works for me. I follow this link. If URL rewrite module is not install then you will have to install this on your instance otherwise only this web.config file change will works.

<?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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!