Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is CookieAuthenticationOptions.AuthenticationType used for?

In my application's Asp.Net Identity Auth middleware setup I have

app.UseCookieAuthentication(new CookieAuthenticationOptions {
    LoginPath = new PathString("/Login/"),
    //AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    Provider = new CookieAuthenticationProvider {
    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<MyUserManager, MyUser>(
                        TimeSpan.FromMinutes(30),
                        (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
                    ),
    },
});

I had copied this from another app and I just noticed that if I uncomment the AuthenticationType line, login succeeds (I get a success message in my logger written from my controller) but always redirects back to the login screen.

In the documentation for CookieAuthenticationOptions it says

The AuthenticationType in the options corresponds to the IIdentity AuthenticationType property. A different value may be assigned in order to use the same authentication middleware type more than once in a pipeline.(Inherited from AuthenticationOptions.)

I don't really understand what this means, why this would cause my login request to be redirected (after a successful login no less), nor what this option would be useful for.

like image 284
George Mauer Avatar asked Feb 26 '16 13:02

George Mauer


2 Answers

This is a string and can be anything. But this is an identifier for authentication type. And you can have multiple authentication types: your DB with users, Google, Facebook, etc. As far as I remember this is added as a claim to the generated cookie on sign-in.

You need to know the authentication provider when you sign user out. If your authentication middleware is defined like this:

    app.UseCookieAuthentication(new CookieAuthenticationOptions {
        LoginPath = new PathString("/Login/"),
        AuthenticationType = "My-Magical-Authentication",
        // etc...
        },
    });

then to sign user out you need the same magic string: AuthenticationManager.SignOut("My-Magical-Authentication")

Also this string is passed into ClaimsIdentity when principal is created. And without AuthenticationType principal can't be authenticated because:

/// <summary>
/// Gets a value that indicates whether the identity has been authenticated.
/// </summary>
/// 
/// <returns>
/// true if the identity has been authenticated; otherwise, false.
/// </returns>
public virtual bool IsAuthenticated
{
  get
  {
    return !string.IsNullOrEmpty(this.m_authenticationType);
  }
}

This method IsAuthenticated is used through entire MVC code-base, with all authentication mechanisms relying on this.

Also theoretically you can sign in through multiple providers and sign out only a single one of them at a time, leaving the rest of providers still authenticated. Though I have never tried this.

Another use I just found - if you don't provide CookieName in your middleware configuration, then Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationType; (see second if statement in constructor).

I'm sure there are more places where it is used. But the most important is to provide it and be consistent with the name or you'll get subtle bugs in authentication system.

like image 155
trailmax Avatar answered Oct 16 '22 18:10

trailmax


I don't know the whole answer, but I have an example on what it would be useful for.

I have a multi-tenant website: the website runs as a single instance multiple domains are linked to it. Each domain is a separate tenant (with a separate set of users). To implement a Facebook login per tenant, I needed a Facebook app per tenant. To configure this, I had to set a unique CallbackPath and a unique AuthenticationType per tenant:

var facebookOptions = new FacebookAuthenticationOptions
{
    AuthenticationType = "Facebook-{tenantID}", 
    CallbackPath = new PathString($"/signin-facebook-{tenantID}")
}

I thought it was also used as a cookie name, but that's not the case for an external login like FacebookAuthentication. What I did notice is that this value of AuthenticationType popped up when requesting:

  1. the IdentityUserLogin.LoginProvider via authenticationManager.GetExternalLoginInfoAsync()
  2. the AuthenticationDescription.AuthenticationType via authenticationManager.GetExternalAuthenticationTypes() (seems logical ;-))
  3. The IdentityUserLogin.LoginProvider for each user.Logins (similar to 1)

And last but not least: the value of AuthenticationType is stored in the database column AspNetUserLogins.LoginProvider.

like image 4
kloarubeek Avatar answered Oct 16 '22 19:10

kloarubeek