Как создать SecurityStamp для AspNetUser в ASP .NET MVC 5

Когда я создаю пользователя с помощью действия «Регистрация», когда приложение работает, пользователь приложения получает SecurityStamp. Когда я добавляю пользователя:

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);
                        }
                    }

                }
            }

пользователь не получает штамп безопасности:

введите здесь описание изображения

а затем, когда я хочу войти, я получаю:

введите здесь описание изображения

Вопрос: как сгенерировать SecurityStamp для пользователя?


person Yoda    schedule 18.08.2014    source источник
comment
Почему бы вам не использовать UserManager.CreateAsync(); вместо этого?   -  person Moe Bataineh    schedule 18.08.2014
comment
@MohamadBataineh UserManager у меня не сработал. Возможно, я где-то ошибся: вот тема --› stackoverflow.com/questions/25354751/   -  person Yoda    schedule 18.08.2014


Ответы (2)


Защитный штамп может быть каким угодно. Его часто ошибочно принимают за отметку времени, но это не так. Он будет переопределен удостоверением ASP.NET, если что-то изменится в объекте пользователя. Если вы работаете с контекстом напрямую, лучше всего создать новый Guid и использовать его в качестве штампа. Вот простой пример:

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()
                         }
                };
person Horizon_Net    schedule 18.08.2014
comment
Это сработало, знаете, почему я не мог войти в систему без этого набора SequirtyStamp? - person Yoda; 20.08.2014
comment
@Yoda У меня была такая же проблема некоторое время назад, но я могу только догадываться. Я думаю, что это свойство будет проверено фреймворком во время процесса входа в систему, чтобы убедиться, что ваша база данных не была повреждена (или что-то в этом роде). Согласно этому post, он используется для аннулирования файлов cookie. - person Horizon_Net; 20.08.2014
comment
Штамп безопасности используется для аннулирования файла cookie входа пользователя и принудительного повторного входа в систему. stackoverflow.com/a/19505060/749626 - person CowboyBebop; 11.11.2015
comment
Если он равен нулю, сброс пароля может не сработать — неверный токен. ошибка - person Savage; 21.04.2016

Если мы заглянем внутрь данных IdentityUser таблицы AspNetUsers, мы увидим, что SecurityStamp имеет форму, отличную от обычной GUID:

Идентификация пользователей AspNet

Это связано с тем, что GUID преобразуется в строку карты HEX.

Мы можем создать функцию для создания новых штампов безопасности, которая будет генерировать новый GUID и преобразовывать его в строку карты HEX:

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

Вы можете проверить его выполнение на этой .NET Fiddle.

Итак, если мы хотим засеять Identity Users, мы можем использовать его для генерации SecurityStamp:

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

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

Предупреждение. Будьте очень осторожны и не используйте приведенный выше пример для заполнения, потому что он будет изменять данные каждый раз, когда мы создаем новую миграцию. Данные заполнения всегда должны быть предварительно сгенерированы при использовании HasData, а не динамически встроены.

person Christos Lytras    schedule 26.05.2020