Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppHarbor's Reverse Proxy causing issues with SSL and app.UseOAuthBearerTokens ASP.NET MVC 5

Applications at AppHarbor sit behind an NGINX load balancer. Because of this, all requests that hit the client app will come over HTTP as the SSL will be handled by this front end.

ASP.NET MVC's OAuth 2 OAuthAuthorizationServerOptions has options to restrict access to token requests to only use HTTPS. The problem is, unlike a Controller or ApiController, I don't know how to allow these forwarded requests through when I specify AllowInsecureHttp = false.

Specifically, in the app startup/config:

  app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions {
            AllowInsecureHttp = true,
   });

Needs to somehow do this check internally and if it's true, treat it as SSL:

HttpContext.Request.Headers["X-Forwarded-Proto"] == "https"

Here's how I do it using MVC Controller's by applying a custom Filter Attribute: https://gist.github.com/runesoerensen/915869

like image 537
Oliver Kane Avatar asked Jun 13 '14 20:06

Oliver Kane


1 Answers

You could try and register some middleware that can modify requests based on the headers forwarded by nginx. You probably also want to set the remote IP address to the value of the X-Forwarded-For header.

Something like this should work (untested):

public class AppHarborMiddleware : OwinMiddleware
{
    public AppHarborMiddleware(OwinMiddleware next)
        : base(next)
    {
    }

    public override Task Invoke(IOwinContext context)
    {
        if (string.Equals(context.Request.Headers["X-Forwarded-Proto"], "https", StringComparison.InvariantCultureIgnoreCase))
        {
            context.Request.Scheme = "https";
        }

        var forwardedForHeader = context.Request.Headers["X-Forwarded-For"];
        if (!string.IsNullOrEmpty(forwardedForHeader))
        {
            context.Request.RemoteIpAddress = forwardedForHeader;
        }
        return Next.Invoke(context);
    }
}

Make sure to add it before you configure the authentication middleware:

app.Use<AppHarborMiddleware>();
app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
{
    AllowInsecureHttp = false,
});
like image 168
runesoerensen Avatar answered Oct 20 '22 17:10

runesoerensen