OWIN and WS-FED - session cookie is not set resulting in infinite loop

Jun 5, 2014 at 9:22 AM

I am using the following code to use ADFS for authentication but when ADFS redirects me back my app is not setting the auth cookie. What am I missing? and what should SignInAsAuthenticationType be?
app.UseCookieAuthentication(new CookieAuthenticationOptions
                AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType

            app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()
                MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
                Wtrealm = "https://localhost/WebApplication2/",
                SignInAsAuthenticationType = "don't know what this is"
Jun 5, 2014 at 6:51 PM
Where did you get that sample? I've seen several people make the same mistake lately. Try this:
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()
  MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
  Wtrealm = "https://localhost/WebApplication2/",
  // SignInAsAuthenticationType = // This is picked up automatically from the default set above
Marked as answer by cosminonea on 6/5/2014 at 2:00 PM
Jun 5, 2014 at 9:32 PM
That worked, thanks.

I think I found a problem though. My app can be accessed on http as well as https. If I go to the http url and then click a protected link that triggers the authentication then I get into an infinite loop and ADFS shows an error.

When I go to the https url directly then the authentication is fine and I get redirected to my app properly.
Jun 5, 2014 at 9:41 PM
I fixed it by setting the cookie options
app.UseCookieAuthentication(new CookieAuthenticationOptions()
                CookieSecure = CookieSecureOption.Never
Jun 5, 2014 at 9:44 PM
That's not recommended. That leaves your cookie vulnerable to high jacking. It's better to require https for any authenticated resource.
Jun 6, 2014 at 8:31 AM
Here is another case where it seems to go into an infinite loop.

If I secure a controller action with the Authorize attribute and specify a role that the current user is not part of then instead of getting an unauthorized error page it starts the federation protocol again and enters an infinite loop.
[Authorize(Roles = "Developers")]
        public ActionResult Contact()
            ViewBag.Message = "Your contact page.";

            return View();
If the current user is not a developer the issue occurs.

Is this a problem with the code or my misconfiguration of the middleware? How do you differentiate between unauthorized because unauthenticated and unauthorized because not part of a role?
Jun 6, 2014 at 2:39 PM
Hmm, I'd have to dig into MVC's Authorize attribute. Here's how I'd expect the flow to work:
  • Anonymous user comes in, hits this secured endpoint, Authorize sends a 401, and the auth middleware kicks in.
  • The user authenticates and comes back to the secured endpoint, Authorize sees that the user does not have the required claims/roles, and sends a 403 (Forbidden) which does not trigger the auth middleware.
Jun 6, 2014 at 7:20 PM
Yeah, I think this end-to-end scenario is broken.

The Authorize attribute currently assumes that a 401 will either be sent back to the client, or you will redirect to a local login page where they will pick an authentication type and start the flow. However, with WsFed's AuthenticationMode set to Active (default), it gets triggered first by the 401 and puts you in an infinite loop.

Short term I think you'll have to try conforming to the old model by setting WsFed to Passive, and setting up the cookie middleware to redirect to a login page. This is how the VS templates work.

Long term, I think we need to work to make the Authorize attribute/processing smarter and more flexible.
Marked as answer by Tratcher on 6/6/2014 at 12:37 PM
Jun 6, 2014 at 7:37 PM
Jul 8, 2014 at 12:34 AM
Edited Jul 8, 2014 at 1:06 AM
Feb 9, 2015 at 6:05 PM
I had what appeared to be a similar issue when debugging locally after I migrated my entire project. After almost a day of being very confused and finally realized that when I run the cloud project locally, it was remapping ports 80 - 81 and 443 - 444. This caused an infinite loop when it hit the authorise attribute on the action. It was not very evident and only become apparent when I started with the samples and could recreate the issue.