What is the correct way to trigger OWIN cookie middleware set to passive authentication mode?

10,933

Solution 1

I'm not sure of the exact question you have.

OWIN is a pipeline that runs all the middleware modules registered. You can have multiple authentication types of middleware registered.

The cookie decrypts to the identity. If you change the authentication type to external bearer it will be a bearer token in the cookie.

I'm not sure why its not working for you, this is what I use. (I haven't looked at the external logins of the template)

   // Enable the application to use a cookie to store information for the signed in user
  app.UseCookieAuthentication(new CookieAuthenticationOptions
            {   
                //just to show bearer
                AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
                LoginPath = new PathString("/Account/Login"),
             }

Good explanation of active vs. passive, from Mr. Brock Allen himself.

Active vs Passive authentication middleware

One question that arises — if the new templates have multiple OWIN authentication middleware configured, then which one is really used? Well, OWIN authentication middleware has the concept of passive vs. active. Active middleware always look at every incoming request and attempt to authenticate the call and if successful they create a principal that represents the current user and assign that principal to the hosting environment. Passive middleware, on the other hand, only inspects the request when asked to. In the case of the default templates from Visual Studio 2013, all the middleware configured are all passive by default, except for the “main” cookie authentication middleware (turns out there are two cookie middlewares that get used in some templates — the main one and another one for external identity providers and this other one is marked as passive).

Solution 2

I arrived here because I was asking the same question. It turns out there is no correct way because it cannot be done. The Authentication middleware calls the "Invoke" method to test whether it should do anything in passive mode. In middleware such as the OpenIdConnect middleware, this method is over-ridden such that it checks the request path, and if it's the Options.RedirectUri then the the middleware does something, sets up the Response object to do something like a redirect and returns "true" to indicate that the request has been handled, and then the middleware stack is unwound and the response processed. The CookieAuthenticationMiddleware's Invoke method does nothing, it only returns 'false', which means that control is passed to the next middleware in the chain. So, the result is that CookieAuthenticationMiddleware cannot be used for authentication in passive mode. I found this blog post really helpful: https://chris.59north.com/post/Understanding-OWIN-(Katana)-Authentication-Middleware . Also, take a look at the Katana source code: https://github.com/aspnet/AspNetKatana

Share:
10,933
Steve
Author by

Steve

Updated on July 20, 2022

Comments

  • Steve
    Steve almost 2 years

    I have been following the OAuth 2.0 Authorization Server sample code http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server

    As well as looking at the nugget package Microsoft.aspnet.identity.samples package (install-package Microsoft.aspnet.identity.samples -Pre)

    and am trying to get my head around how passive vs. active cookie middleware works.

    In the Authorization server example, the "Application" cookie is set to passive. In the Identity samples, "ApplicationCookie" is active.

    When I read about this property, it explains that passive middleware is only triggered when requested by a matching AuthenticationType.

    If I edit the startup.auth.cs file in the Microsoft.aspnet.identity.samples and set the application cookie to passive, then log in, it seems to validate, but doesn't log me in.

    Digging deeper into the code, I see that the account controller boil down to a call to SignInHelper.SignInAsync

    This method gets a claimsidentity from the user which is a call to: CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)

    I am obviously not understanding something, since from what I read and can tell, the cookie has the same AuthenticationType as the Claim, but when the Authentication.SignIn is called, the Cookie doesn't seem to get set and I am returned to the main page with options to register and login.

    To duplicate the issue, start a new project empty asp.net application, then install the Identity sample package, then change startup.auth.cs's app.useCookieAuthentication to:

    app.UseCookieAuthentication(new CookieAuthenticationOptions {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
                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))
                }
            });
    

    I have tried changing the cookie name in the startup.auth.cs and adding the "custom" name to the code that generates the claim to no avail.

    I am going to keep researching, but thought I would reach out to the community in the meantime.