Жодного IUserTokenProvider не зареєстровано


101

Нещодавно я оновив Asp.Net Identity Coreсвою заявку від 1,0 до 2,0.

Є нові функції, які я хотів спробувати GenerateEmailConfirmationToken, і т.д.

Я використовую цей проект як орієнтир.

Коли користувач намагається зареєструватися, я отримую помилку під час виконання Post методу реєстрації

private readonly UserManager<ApplicationUser> _userManager;     

public ActionResult Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var ifUserEXists = _userManager.FindByName(model.EmailId);
        if (ifUserEXists == null) return View(model);
        var confirmationToken = _userRepository.CreateConfirmationToken();//this is how i'm generating token currently.                
        var result = _userRepository.CreateUser(model,confirmationToken);
        var user = _userManager.FindByName(model.EmailId);
        if (result)
        {
            var code = _userManager.GenerateEmailConfirmationToken(user.Id);//error here
            _userRepository.SendEmailConfirmation(model.EmailId, model.FirstName, confirmationToken);
            //Information("An email is sent to your email address. Please follow the link to activate your account.");
            return View("~/Views/Account/Thank_You_For_Registering.cshtml");
        }     
    }
    
    //Error("Sorry! email address already exists. Please try again with different email id.");
    ModelState.AddModelError(string.Empty, Resource.AccountController_Register_Sorry__User_already_exists__please_try_again_);
    return View(model);
}

У рядку

 var code = _userManager.GenerateEmailConfirmationToken(user.Id);

Я отримую помилку, кажучи:

No IUserTokenProvider is registered.

Поки що я просто хотів подивитися, який код він генерує. Чи є якась зміна, яку мені потрібно внести до свого ApplicationUserкласу, який успадковується від IdentityUserкласу?

Або є щось, що мені потрібно змінити, щоб ці функції працювали?


1
Чи є спосіб перевірити, чи існує користувач на основі інших полів, ніж адреса електронної пошти? Наприклад, якби у мене було два поля під назвою CustomerNumber та Поштовий індекс для користувачів, які вже існували в базі даних, щоб зупинити будь-кого від реєстрації
Jay

Відповіді:


127

Ви повинні вказати a, UserTokenProviderщоб генерувати маркер.

using Microsoft.Owin.Security.DataProtection;
using Microsoft.AspNet.Identity.Owin;
// ...

var provider = new DpapiDataProtectionProvider("SampleAppName");

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());

userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
    provider.Create("SampleTokenName"));

Також слід прочитати цю статтю: Додавання двофакторної автентифікації до програми за допомогою ідентичності ASP.NET .


5
що таке "Sample"і "EmailConfirmation"? якийсь текст, який може бути будь-яким?
Кіберкоп

2
"Sample" = AppName, "EmailConfirmation" = мета (як імена параметрів)
meziantou

5
Так, але вам доведеться використовувати те ж саме для створення та перевірки токенів
meziantou

1
Посилання в порядку. Ви ставите цей код там, де ви ініціалізуєтеUserManager
meziantou

це спричиняє "Неможливо завантажити тип" System.Security.Cryptography.DpapiDataProtector "від збирання в .netcore
TAHA SULTAN TEMURI

25

У ASP.NET Core зараз можливо налаштувати службу за замовчуванням у Startup.cs таким чином:

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddDefaultTokenProviders();

Не потрібно дзвонити DpapiDataProtectionProviderабо щось подібне. DefaultTokenProviders () піклується про виклик GenerateEmailConfirmationToken від UserManager.


21

На додаток до прийнятої відповіді, я хочу додати, що цей підхід не працюватиме в веб-сайтах Azure, ви отримаєте CryptographicException замість маркера.

Щоб виправити це за Azure, реалізуйте власний IDataProtector: див. Цю відповідь

Трохи детальніше в блозі


13

Моє рішення:

    var provider = new DpapiDataProtectionProvider("YourAppName");
    UserManager.UserTokenProvider = new DataProtectorTokenProvider<User, string>(provider.Create("UserToken")) 
        as IUserTokenProvider<User, string>;

Моя проблема з цим кодом вирішена.
Успіхів друзі.


використання Microsoft.Owin.Security.DataProtection;
Амін Ґадері

Мені довелося використовувати DataProtectorTokenProvider <IdentityUser, string> замість <User, string> для обох дженериків. Також UserId в GeneratePasswordResetToken є ідентифікаційним рядком ідентифікатором, а не ім'ям користувача або електронною поштою.
Ден Рендольф

7

У випадку, якщо хтось зробить ту саму помилку, що і я. Я спробував зробити таку функцію, як наведена нижче, і досить впевнено помилка "Не зареєстровано жодного IUserTokenProvider." Пішла. Однак як тільки я спробував використати посилання, згенероване з "callbackUrl", я отримав помилку "Недійсний маркер". Для того, щоб він працював, вам потрібно отримати HttpContext UserManager. Якщо ви використовуєте стандартну програму ASP.NET MVC 5 з індивідуальними обліковими записами користувачів, ви можете зробити це як нижче.

Код, який працює:

public ActionResult Index()
     {
         //Code to create ResetPassword URL
         var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
         var user = userManager.FindByName("useremail@gmail.com");
         string code = userManager.GeneratePasswordResetToken(user.Id);
         var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
         return View();
     }

Спершу спробуйте, що не працює, No IUserTokenProvider is registered.немає, але створена URL-адреса отримує Invalid token..

public ActionResult NotWorkingCode()
     {
             //DOES NOT WORK - When used the error "Invalid token." will always trigger.
             var provider = new DpapiDataProtectionProvider("ApplicationName");
             var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));
             userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("ASP.NET Identity"));
             var user = userManager.FindByName("useremail@gmail.com");
             string code = userManager.GeneratePasswordResetToken(user.Id);
             var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
             //DOES NOT WORK - When used the error "Invalid token." will always trigger.
         return View();
     }

5

Відповідно до піскерів вище

У startup.cs ви можете використовувати

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddDefaultTokenProviders();

У .net core 2.0 вам може знадобитися додати до startup.cs:

using Microsoft.AspNetCore.Identity;

Це добре працювало для мене.


1
Я думаю, що важливо пам’ятати, що це рішення Asp .NET Core, воно не працюватиме з Asp .NET Framework.
Мачадо

3

Змінюючи файли ідентичності .NET Core, я натрапив на цю помилку:

NotSupportedException: Не зареєстровано IUserTwoFactorTokenProvider з назвою "За замовчуванням".

The

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

Функція не могла генерувати маркер, оскільки жоден провайдер не був доступний при реєстрації нового користувача. Ця помилка, проте, легко виправить!

Якщо ви схожі на мене, ви змінили AddDefaultIdentityв Startup.csфайлі з AddIdentity. Я хотів реалізувати власного користувача, який успадкував від базового користувача. Тим самим я втратив провайдерів жетонів за замовчуванням. Виправлення полягало в тому, щоб додати їх назад AddDefaultTokenProviders().

        services.AddIdentity<User, UserRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

Після цього виправлення все знову працювало!

джерело: https://mattferderer.com/NotSupportedException-No-IUserTwoFactorTokenProvider-tuser-named-default-registered


1

Я отримав таку ж помилку після оновлення ідентичності та виявив, що це було тому, що я використовував Unity.

Дивіться цю тему питання щодо рішення: Зареєструйте IAuthenticationManager в Unity

Також нижче для швидкого ознайомлення:

Ось що я зробив для того, щоб Unity гарно грав з ASP.NET Identity 2.0:

До RegisterTypesметоду в UnityConfigкласі я додав :

container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<AccountController>(new InjectionConstructor());

1
Я стежив за цим, але це не спрацювало (для GeneratePasswordResetToken- але я отримав ту саму помилку "Не зареєстровано жодного IUserTokenProvider"). Після додавання container.RegisterType<ApplicationUserManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()));до UnityConfig.csцього він працював.


0

в IdentityConfig.cs, додайте параметр "двофактор":

        manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        //config sms service 
        manager.SmsService = new Services.SMS();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.