IdentityServer / IdentityServer3.Admin

Sample Admin UI for IdentityServer3
Apache License 2.0
75 stars 77 forks source link

Redirect to authorize endpoint is to http when behind load balancer terminating SSL #30

Closed Toominator closed 8 years ago

Toominator commented 8 years ago

I have IdentityServer3 and Admin in the same host behind a load balancer and I am terminating SSL at the load balancer. I therefore have RequireSsl=false and the PublicOrigin of IdentityServer set to the https address of the load balancer. When logging in to Admin the redirect is to http instead of https and so fails (e.g. http://identity.abc.com/admin/authorize?state=1180072232507164&client_id=idAdmin&response_type=token)

Toominator commented 8 years ago

Yes, I do.

And you have RequiresSsl = false in your AdminHostSecurityConfiguration ?


From: Allan Hardy notifications@github.com Sent: 20 April 2016 13:48 To: IdentityServer/IdentityServer3.Admin Cc: Michael Toomey; Author Subject: Re: [IdentityServer/IdentityServer3.Admin] Redirect to authorize endpoint is to http when behind load balancer terminating SSL (#30)

Same setup works fine for me.

Do you have the Authority on OpenIdConnectAuthenticationOptions set as https in the Admin?

You are receiving this because you authored the thread. Reply to this email directly or view it on GitHubhttps://github.com/IdentityServer/IdentityServer3.Admin/issues/30#issuecomment-212409896


This email has been checked for known viruses - AVEVA Group IT Services.


The information contained in this message, together with any attachments, may be legally privileged or confidential and is intended only for the use of the individual(s) or entity named above. If you are not the intended recipient, you are notified that any dissemination, distribution or copying of this message is strictly prohibited. If you have received this message in error, please notify us immediately before deleting it.

This message has been checked for all known viruses through Microsoft Online Protection, for and on behalf of the AVEVA Group. Although no viruses were found it is the recipient's responsibility to ensure that this message is safe for use on their system.

AVEVA Group plc is a Public Limited Company registered in England with registered number 2937296. The registered office of AVEVA Group plc is High Cross, Madingley Road, Cambridge, England CB3 0HB

senseicz commented 8 years ago

When you terminate SSL on load balancer, this balancer will in most cases add special HTTP header "X-Forwarded-Proto" with value either http or https to give back-end server an idea whether initial call was over http or https. Without further thinking what it may cause, maybe it would be enough just to modify condition in IdentityAdminAppBuilderExtensions.cs, something like changing following code:

app.Use(async (ctx, next) =>
{
     if (!ctx.Request.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) && 
         options.AdminSecurityConfiguration.RequireSsl)
    {
          ctx.Response.Write("HTTPS required");
    }
    else
    {
         await next();
    }
});

to:

app.Use(async (ctx, next) =>
{
    if (!string.IsNullOrEmpty(ctx.Request.Headers["X-Forwarded-Proto"])) //behind load balancer
    {
        if (!ctx.Request.Headers["X-Forwarded-Proto"].Equals("https", StringComparison.OrdinalIgnoreCase) &&
            options.AdminSecurityConfiguration.RequireSsl)
        {
            ctx.Response.Write("HTTPS required");
        }
        else
        {
            await next();
        }
    }
    else //direct traffic
    {
        if (!ctx.Request.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
            options.AdminSecurityConfiguration.RequireSsl)
        {
            ctx.Response.Write("HTTPS required");
        }
        else
        {
            await next();
        }
    }
});

This way, you'd be able to leave RequireSsl = true; , although question is what it will do next when AccessToken is returned upon login.

HappyCodeSloth commented 8 years ago

I have had a go at getting in the same scenario. Https terminating at load balancer with http between load balancer and the web servers.

@senseicz this was very useful but it only got me one hop of the way. When you click login it goes to the /authorize endpoint. Because the OAuthAuthorizationServer server is now running requiring ssl this request fails as the request comes in as http.

So, I tried again using RequireSsl false on the IdentityAdmin.

The problem that I can see is when the identity server responds it first POST's the identity token to the admin endpoint https://myserver/admin which responds with a 302 and Location http://myserver/admin/authorize?state=13284069124445454&client_id=idAdmin&response_type=token

This is where it obviously can't find the endpoint as it is http and needs to be https. I cant work out where this POST request is handled in IdentityAdmin. The weird bit is it doesnt seem to come through the OWIN pipeline at all.

The only thought I had to solve this was a bit of OwinMiddleware that intercepts this response modifying the Location to be the https address. However, as I said the POST from the IdentityServer to the IdentityAdmin endpoint doesn't seem to go through the IdentityAdmin OWIN pipeline.

Any other ideas anyone?

HappyCodeSloth commented 8 years ago

Doh. I didn't put my OWIN Middleware early enough in the pipeline. I finally got this "working". i.e. It's a hack.

app.Use(async (ctx, next) =>`
{
    await next();
    if (ctx.Response.StatusCode == 302 && ctx.Response.Headers.Any(x => x.Key == "Location"))`
    {
        ctx.Response.Headers["Location"] = ctx.Response.Headers["Location"].Replace("http://", "https://");
    }
});

So, to cludge this until I think of a better plan I replace the protocol on all the links. i.e. .Replace("http://", "https://")

HappyCodeSloth commented 8 years ago

The solution I came up with for the AbsoluteUri's used in the REST API was to make them relative to the authority. See pull request #38

iBoonz commented 8 years ago

Merged pull request, ty @KMC13

senseicz commented 8 years ago

May I ask for these changes to made a new beta release and push them out via new NuGet package? Would help me a lot, many thanks in advance :-)