Yoda
Yoda

Reputation: 18068

How to create SecurityStamp for AspNetUser in ASP .NET MVC 5

When I create user by Register action whe application is running the application user gets SecurityStamp. When I add user by:

if (!context.Users.Any()) {
    System.Diagnostics.Debug.WriteLine("INSIDE");
    var hasher = new PasswordHasher();
    try {
        var users = new List<ApplicationUser> { 
            new ApplicationUser { PasswordHash = hasher.HashPassword("TestPass44!"), Email = "[email protected]", UserName = "[email protected]" },
            new ApplicationUser { PasswordHash = hasher.HashPassword("TestPass44!"), Email = "[email protected]", UserName = "[email protected]" }
        };
        users.ForEach(user => context.Users.AddOrUpdate(user));
        context.SaveChanges();
    } catch (DbEntityValidationException e) {
        System.Diagnostics.Debug.WriteLine("EXC: ");
        foreach (DbEntityValidationResult result in e.EntityValidationErrors) {
            foreach (DbValidationError error in result.ValidationErrors) {
                System.Diagnostics.Debug.WriteLine(error.ErrorMessage);
            }
        }
    }
}

user doesn't get security stamp:

enter image description here

and then when I want to login I get:

enter image description here

Question: How to generate SecurityStamp for user?

Upvotes: 27

Views: 32960

Answers (2)

Horizon_Net
Horizon_Net

Reputation: 5989

The security stamp can be anything you want. It is often mistaken to be a timestamp, but it is not. It will be overriden by ASP.NET Identity if something changes on the user entity. If you're working on the context directly the best way would to generate a new Guid and use it as the stamp. Here's a simple example:

var users = new List<ApplicationUser> 
{ 
    new ApplicationUser
    {
        PasswordHash = hasher.HashPassword("TestPass44!"), 
        Email = "[email protected]", 
        UserName = "[email protected]", 
        SecurityStamp = Guid.NewGuid().ToString()
    },
    new ApplicationUser
    {
        PasswordHash = hasher.HashPassword("TestPass44!"),
        Email = "[email protected]", 
        UserName = "[email protected]", 
        SecurityStamp = Guid.NewGuid().ToString()
    }
};

Upvotes: 42

Christos Lytras
Christos Lytras

Reputation: 37318

If we look inside IdentityUser table AspNetUsers data, we'll see that SecurityStamp has a different form than a normal GUID:

Identity AspNetUsers

This is because the GUID is converted to a HEX map string.

We can create a function to generate new Security Stamps, that it will generate a new GUID and convert it to a HEX map string:

Func<string> GenerateSecurityStamp = delegate()
{
    var guid = Guid.NewGuid();
    return String.Concat(Array.ConvertAll(guid.ToByteArray(), b => b.ToString("X2")));
};

You can check it running to this .NET Fiddle.

So, if we want to seed Identity Users, we can use it to generate the SecurityStamp:

modelBuilder.Entity<IdentityUser>().HasData(new ApplicationUser
{
    ...

    // Security stamp is a GUID bytes to HEX string
    SecurityStamp = GenerateSecurityStamp(),
});

Warning: Be very careful and don't use the above example for seeding, because it will change the data every time we create a new migration. Seeding data should always be pre-generated when using HasData and not dynamic inline generated.

Upvotes: 3

Related Questions