Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.net Identity SecurityStampValidator OnValidateIdentity regenerateIdentity parameter

Can anyone explain why the ApplicationUser class creates the following helper function?

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User, int> manager)
{
    // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
    var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
    // Add custom user claims here
    return userIdentity;
}

The only place I can find it being used is in the Startup.Auth.cs file, as the regenerateIdentity callback parameter for the SecurityStampValidator.OnValidateEntity function:

OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User, int>(
     validateInterval: TimeSpan.FromSeconds(15),
     regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
     getUserIdCallback: (id) => id.GetUserId<int>())

As you can see from the helper it just turns around and calls manager.CreatedIdentityAsync. Is there a reason they "polluted" the ApplicationUser class with the helper method rather than setting up OnValidateEntity as follows?

OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User, int>(
     validateInterval: TimeSpan.FromSeconds(15),
     regenerateIdentityCallback: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie),
     getUserIdCallback: (id) => id.GetUserId<int>())
like image 714
Sam Avatar asked Mar 09 '15 16:03

Sam


1 Answers

*Editted for clarity and simplicity

By abstracting the Identity Generation method into the user class, We are allowed a point of extensibility.

Imagine a scenario in which your application has several different user types, each one would be able to implement their own regeneration logic without having to have separate authentication types. Take the helper method in the ApplicationUser subclass of IdentityUser base class.

public class ApplicationUser : IdentityUser
{      
    public string NickName {get; set; }
    public DateTime BirthDay {get; set;}


    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

We can now separate our claims into different user classes without having to modify the OWIN authentication pipeline, or create a new CookieAuthenticationProvider for each type simply by subclassing the base IdentityUser.

tldr;

It pushes the identity regeneration responsibilities onto the user class that is being regenerated. Similar to a factory method pattern.

like image 121
Jake Garrison Avatar answered Oct 26 '22 13:10

Jake Garrison