Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure UseCookieAuthentication behind a load balancer

I am configuring a .netcore application to use OIDC authenication (provided by IdentityServer).

I have included the following code in my StartUp

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "Cookies",
    AutomaticAuthenticate = true,
    ExpireTimeSpan = TimeSpan.FromMinutes(60)
});

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = "oidc",
    SignInScheme = "Cookies",

    Authority = "https://myauthority",
    ClientId = "myclient",
    CallbackPath = "/",
    ResponseType = "id_token token",
    Scope = { "openid", "profile", "email" },
});

The application is hosted on AWS, within a docker running in ECS. It runs behind an application load balancer listening on https.

I have found that because my application is not itself using https (because the https is terminated by the load balancer), the OIDC middleware is generating an incorrect return URL when redirecting to the OIDC server - the URL it generates begins http://.

The return URL is generated by a method named BuildRedirectUri within the AuthenticationHandler base class. It just uses the protocol on which it received the request - there doesn't seem any way to override this.

protected string BuildRedirectUri(string targetPath)
{
    return this.Request.Scheme + "://" + this.Request.Host + this.OriginalPathBase + targetPath;
}

So given it doesn't seem possible to configure the middleware to force a HTTP redirect, what other options do I have?

Should I write a 'higher' middleware component to listen for redirect requests and modify the protocol? Or is there a better way to solve this problem?

like image 512
sandy Avatar asked Apr 06 '17 23:04

sandy


Video Answer


1 Answers

When a proxy is used (for example putting IIS in front of Kestrel or as in your case, a load balancer), the proxy should be sending X-Forwarded-For and X-Forwarded-Proto HTTP headers. It's the latter one that passes along the original protocol that was requested. Fortunately there is a solution, and that is to use the ForwardedHeaders middleware from the Microsoft.AspNetCore.HttpOverrides package. So add that package and then add this code to your middleware pipeline:

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

Place this as early as you can in your pipeline.

like image 67
DavidG Avatar answered Sep 22 '22 06:09

DavidG