ASP.Net Core LoginExternal Not Working with HTTPS

I’m having a problem using a load balancer before a .net core app on redirect from auth0 signin.

The original post is this one and I think I have the same problem, but with haproxy instead of nginx: https://auth0.com/forum/t/asp-net-core-loginexternal-not-working-with-https/3888.

We are using a Haproxy to offload the ssl (all requests are https) and redirecting internally to a linux server running Kestrel on Http. Using the setting CallbackPath = new PathString("/signin-auth0") in my OpenIdConnectOptions always returns a http:// link. When the user is redirected i get a 404 page not found error. The https POST gets a 301 status code but never reaches his destination.

Has anyone had the same problem ? Is there a workaround? We can not change the internal structure and upgrade the Kestrel to https, like the old forum post suggested.

I was thinking about using the lock widget, but i would like to keep the login external (we have multiple apps with multiple third-party apps).

If I understood the situation correctly the issue is that the relative CallbackPath is used to construct the absolute redirect URI sent to the identity provider (in this case Auth0). Given that ASP .NET Core is running behind a load balancer that terminates TLS, the runtime thinks it’s being accessed using HTTP instead of HTTPS and as such constructs a redirect URI with the incorrect scheme.

If that’s the case, you can use the more advanced options in OpenIdConnectOptions to override this behavior, more specifically, if you use the OnRedirectToIdentityProvider event you can override the redirect URI that will be sent to the identity provider.

The above example shows how to override just the scheme component to always be HTTPS:

var options = new OpenIdConnectOptions("Auth0") {
    // other options
    Events = new OpenIdConnectEvents {
        OnRedirectToIdentityProvider = context => {
            var builder = new UriBuilder(context.ProtocolMessage.RedirectUri);

            builder.Scheme = "https";

            context.ProtocolMessage.RedirectUri = builder.ToString();

            return Task.FromResult(0);
        }
    }
};

Hi,

Thank you for your quick answer, this almost solved my problem, on redirect I still had an SSL_ERROR. I solved it by adding the uri i needed into the UriBuild paramerter like this:

var builder = new UriBuilder("https://url.domain.XX/signin-auth0"); context.ProtocolMessage.RedirectUri = builder.ToString();

and it works now !

thank you very much!

I too had exactly the same issue, and using this answer and your comment helped fixed this issue. As many users are likely to be using load balancers, it would be great if the Auth0 team wrote an official guide for dealing with this scenario, to stop developers writing potentially “hacky” workarounds.

You’re better off setting up the application to work correctly behind a SSL terminated load balancer. The above solutions will work, but they work explicitly for Auth0 and not other scenarios (like local redirects).

You need to check the specific load balancer you’re using, but most forward the original protocol as a HTTP request header called X-Forwarded-Proto.

For MVC Core applications, this is the extension class you’ll want to use. The following will generally make the quickstart code work w/o any additional handlers:

        //forward headers from the LB
        var forwardOpts = new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor
        };
        //TODO: Set this up to only accept the forwarded headers from the load balancer
        forwardOpts.KnownNetworks.Clear();
        forwardOpts.KnownProxies.Clear();
        app.UseForwardedHeaders(forwardOpts);

The known networks / known proxies lists take a IPNetwork that you can use to restrict forwarded headers to known hosts. The code above will accept the headers from anyone - useful for trying it out, but I wouldn’t go to production like that.