alfredbulbasaur alfredbulbasaur - 1 month ago 23
ASP.NET (C#) Question

ASP.NET MVC site not working correctly behind AWS ELB

I'm trying to deploy an ASP.NET MVC web application, which uses individual user accounts, to an AWS server, which is using an elastic load balancer (ELB). I've deployed the site to IIS on the AWS app server, connected it to my AWS SQL server, and it works as expected on the server (and indeed when I run it in Visual Studio or deploy to an internal server).

The problem comes when accessing it remotely, which of course goes via the ELB.



So basically, if I'm logged in, it's fine. If I'm not logged in, the login page is fine but nothing else is. My thinking, along with a colleague from our internal team who works with AWS (he isn't able to help me btw, I've asked!) is that when I get redirected to the login page, it's a HTTP request and not HTTPS, and that's the cause of the issue, but no matter what I've tried I can't get it to redirect with HTTPS. I've tried:


  • adding rules in my web.config file to pick up forwarded requested and redirect them to HTTPS - which doesn't seem to have made any noticeable difference

  • various different attributes added to either my FilterConfig or the Login action

  • adding rules directly in IIS using URL Rewrite



Obviously my workaround is to get everyone to go to the login page and start there rather than just the root URL, but I'd really like to get this sorted as if redirecting doesn't work here, I can see it not working elsewhere and potentially causing issues.

Update as requested: I don't actually have any control over my ELB as that's done by a different team, but my understanding from speaking to the team is that it accepts traffic as HTTPS and then passes it on to the server as HTTP.

Answer

Your MVC application is configured to redirect to an absolute http URL rather than a relative URL when the user needs to sign-in.

For new MVC applications that are based on the Owin middleware, this is configured in App_Start/Startup.Auth.cs.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        // Enables the application to validate the security stamp when the user logs in.
        // This is a security feature which is used when you change a password or add an external login to your account.  
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    }
});

and add the following after the OnValidateIdentity property:

OnApplyRedirect = ApplyRedirect  

Then, later in the class, add the following function:

private static void ApplyRedirect(CookieApplyRedirectContext context)
{
    Uri absoluteUri;
    if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
    {
        context.Response.Redirect(absoluteUri.PathAndQuery);
        return;
    }

    context.Response.Redirect(context.RedirectUri);
}

Basically, this is converting the absolute URL to a relative URL. The relative URL then is passed back to the browser. Since the redirect is relative, it should maintain the https URL.