Нет IUserTokenProvider зарегистрирован
Недавно я обновил Asp.Net Identity Core
моей формы приложения 1.0 до 2.0.
Появились новые функции, которые я хотел попробовать, например, GenerateEmailConfirmationToken
и т.д.
Я использую этот проект как ссылку.
Когда пользователь пытается зарегистрироваться, я получаю сообщение об ошибке при выполнении метода Post для Register
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
Вы должны указать 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.
Ответ 2
В дополнение к принятому ответу я хотел бы добавить, что этот подход не будет работать на веб-сайтах Azure: вместо токена вы получите CryptographicException.
Чтобы исправить это в Azure, внедрите свой собственный IDataProtector: см. Этот ответ
Чуть подробнее в блоге
Ответ 3
В ASP.NET Core теперь можно настроить службу по умолчанию в Startup.cs следующим образом:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
Нет необходимости вызывать DpapiDataProtectionProvider
или что-то в этом роде. DefaultTokenProviders() позаботится о вызове GenerateEmailConfirmationToken из UserManager.
Ответ 4
Мое решение:
var provider = new DpapiDataProtectionProvider("YourAppName");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<User, string>(provider.Create("UserToken"))
as IUserTokenProvider<User, string>;
Моя проблема с этим кодом решена.
Друзья удачи.
Ответ 5
Если кто-то другой совершит ту же ошибку, что и я. Я попытался сделать функцию, подобную приведенной ниже, и достаточно уверен, что ошибка "Нет 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("[email protected]");
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("[email protected]");
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();
}
Ответ 6
В соответствии с pisker выше
В startup.cs вы можете использовать
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
В .net core 2.0 вам может потребоваться добавить в startup.cs:
using Microsoft.AspNetCore.Identity;
Это сработало для меня.
Ответ 7
Вас также могут заинтересовать здесь:
Как реализовать TokenProvider в ASP.NET Identity 1.1 ночная сборка?
для использования реализации поставщика токенов по умолчанию из пакета Microsoft.Identity.Owin
Ответ 8
Я получил ту же ошибку после обновления Identity и обнаружил, что это потому, что я использовал 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());
Ответ 9
в 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"));
}
Ответ 10
При изменении файлов .NET Core Identity я наткнулся на эту ошибку:
NotSupportedException: IUserTwoFactorTokenProvider с именем "По умолчанию" не зарегистрирован.
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