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

1

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

Pozsony answered 13/6, 2014 at 20:48 Comment(0)
S
8

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,
});
Scenic answered 14/6, 2014 at 1:26 Comment(5)
Hells yes! This is just what I was looking for. I didn't realize the request was a mutable thing. This is feeling even more NodeJSy. Ollie happy.Pozsony
Thanks appharbor. You guys rock.Pozsony
I do have one question, is there an exhaustive list of X-Forwarded-* headers that AppHarbor uses? I realized that by using this type of middleware, I can eliminate the need for additional modification elsewhere in my stack for handling similar issues in a single class.Pozsony
Perhaps, these are the full set? d3qt5vpr7p9rgn.cloudfront.net/wp-content/uploads/2013/05/…Pozsony
X-Forwarded-For and X-Forwarded-Proto are the only request headers that will be set/modified by AppHarbor's load balancers.Scenic

© 2022 - 2024 — McMap. All rights reserved.