Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OWIN and Azure AD HTTPS to HTTP Redirect Loop

I am very new to OWIN :). I am trying to have a page with an open public area which will allow anonymous over HTTP, and then a restricted section which will require authentication. I'd like not to force the entire site to be HTTPS for general users.

The issue I have is that I receive the following loop:

  1. http://example.com/authenticatedPage -> 302 Redirect to AD login
  2. Login to AD page HTTP 200. Triggers open of the Azure AD link to site.
  3. Link to site identifies that this is an OWIN redirect and does a 302 redirect to http://example.com/authenticatedPage
  4. Go to 1.

I have tried 3 ways of intercepting the redirect in OWIN but nothing seems to work.

If I begin the session by browsing to https://example.com/ then click on the link to authenticatedPage, then the login works as I expect. i.e.

  1. Load https://example.com/authenticatedPage -> 302 redirect to AD
  2. Login to AD -> loads https://example.com/
  3. 302 redirect to https://example.com/authenticatedPage

Is there anyway to fix this without marking my whole site as requiring SSL?

like image 615
Spence Avatar asked Dec 15 '22 13:12

Spence


1 Answers

The problem is the referrer set by the OIDC middleware in your application. What happens is this:

  1. Enter your application on http://foo.bar and redirect to Identity provider
  2. The IDP/AD redirects to https://foo.bar as configured return URI
  3. Cookie is set by OIDC middleware with Secure flag so for HTTPS only
  4. Middleware redirects to referrer URL which was HTTP
  5. Cookie is not set on HTTP, so back to step 1.

There are multiple solutions to this such as enforcing SSL only, overloading the Authorize attribute and setting the CookieSecure flag to CookieSecureOption.Never (don't do this).

The option I prefer is to fix the Referrer in the middleware itself as such:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = ...
    ClientId = ...
    RedirectUri = "https://foo.bar"
    ResponseType = "id_token",
    Scope = "openid profile",      
    SignInAsAuthenticationType = "Cookies",

    // Deal with the returning tokens
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        AuthorizationCodeReceived = async n =>
        {
            // Enforce the reference/redirect to be HTTPS
            var builder = new UriBuilder(n.AuthenticationTicket.Properties.RedirectUri);
            builder.Scheme = "https";
            builder.Port = 443;
            n.AuthenticationTicket.Properties.RedirectUri = builder.ToString();
        }
    }
});

What this does is rewrite the HTTP on the Referrer URL to HTTPS. This way if the user enters the app on HTTP, he'll be automatically redirected to a HTTPS version after using it.

like image 129
ranieuwe Avatar answered Jan 25 '23 16:01

ranieuwe