Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Owin Startup order affect Cookie Authentication

I have Owin configured to issue both a token and cookie upon authentication:

public void Configuration(IAppBuilder app)
{
    var cookieOptions = new CookieAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        CookieHttpOnly = true, // JavaScript should use the Bearer
        //AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        CookieName = "MyCookie",
        LoginPath = new PathString("/app/index.html#/login"),
    };

    var oAuthServerOptions = new OAuthAuthorizationServerOptions
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
        Provider = new MyAuthorizationServerProvider(),
    };

    var oAuthBearerOptions = new OAuthBearerAuthenticationOptions
    {
    };

    // Must be registered in this order!
    app.UseCookieAuthentication(cookieOptions);
    app.UseOAuthAuthorizationServer(oAuthServerOptions);
    app.UseOAuthBearerAuthentication(oAuthBearerOptions);
 }

This works fine - it issues both the Bearer token for my SPA to call my API and the cookie so my old school MVC pages can be logged in too.

But if I register the OAuth server before declaring that I want to use CookieAuth, no cookie is issued. In other words if I do this, it doesn't work:

app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseCookieAuthentication(cookieOptions);
app.UseOAuthBearerAuthentication(oAuthBearerOptions);

Also, if I uncomment this line, it also doesn't issue the cookie:

AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,

My question is why does the order of registration with Owin matter? And why does setting the AuthenticationType in the cookie as "ApplicationCookie" also make it fail?

like image 264
ThisGuy Avatar asked Sep 30 '22 02:09

ThisGuy


1 Answers

I'm not familiar with the UseOAuthAuthorizationServer() middleware, but I assume it works the same as other external authentication middleware (e.g. the Google middleware).

An authentication middleware that redirects to an external source for authentication, will only be used once, at the start, of each browsing session. It will then defer the authentication of the up-coming requests to a cookie authentication that maintains the session. This is good, because it means the overhead of the external authentication is only done once for each session.

A middleware that wants to set a cookie does typically not do it itself. Instead it sets a property in the Owin context with an AuthenticationResponseGrant. The grant is then processed by the cookie middleware that extracts the identity and sets the cookie.

For this to work:

  1. The cookie handler must be registered before the external authentication middleware in the pipeline.
  2. The authentication type in the AuthenticationResponseGrant must match the type of the cookie middleware.

So changing the order of the registration violates 1. and excluding the authentication type violates 2.

I have written an in depth blog post about it if you want more details.

like image 184
Anders Abel Avatar answered Nov 15 '22 12:11

Anders Abel