没有注册IUserTokenProvider
本文关键字:IUserTokenProvider 注册 | 更新日期: 2023-09-27 17:52:52
我最近更新了我的申请表1.0的Asp.Net Identity Core
到2.0。
有一些我想尝试的新功能,如GenerateEmailConfirmationToken
等。
我用这个项目作为参考。
当用户试图注册时,我在执行register
的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.
现在,我只想看看它会生成什么样的代码。我需要对从IdentityUser
类继承的ApplicationUser
类进行一些更改吗?
或者有什么我需要改变,以获得这些功能的工作?
您必须指定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的应用程序中添加双因素身份验证。净的身份。
现在可以在Startup.cs中配置默认服务,如下所示:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
没有必要调用DpapiDataProtectionProvider
或类似的东西。DefaultTokenProviders()将负责从UserManager调用GenerateEmailConfirmationToken。
除了可接受的答案之外,我想补充一下,这种方法在Azure web站点中不起作用,您将获得CryptographicException而不是令牌。
要在Azure中解决这个问题,实现你自己的IDataProtector:参见这个答案
更多细节
我的解决方案:
var provider = new DpapiDataProtectionProvider("YourAppName");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<User, string>(provider.Create("UserToken"))
as IUserTokenProvider<User, string>;
我的问题解决了。
以防其他人犯和我一样的错误。我试图使一个函数像下面的一个和足够的错误"没有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();
}
根据上面的pisker
在startup.cs中可以使用
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultTokenProviders();
在。net core 2.0中,你可能需要添加startup.cs:
using Microsoft.AspNetCore.Identity;
在修改。net Core的身份文件时,我偶然发现了这个错误:
NotSupportedException:没有IUserTwoFactorTokenProvider命名'Default'已注册。
Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync
函数无法生成令牌,因为在注册新用户时没有可用的提供者。这个错误有一个简单的修复!
如果你像我一样,将Startup.cs
文件中的AddDefaultIdentity
更改为AddIdentity
。我想实现从基本用户继承的自己的用户。通过这样做,我丢失了默认的令牌提供程序。修复方法是将它们添加回AddDefaultTokenProviders()
。
services.AddIdentity<User, UserRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
修复后,一切又正常了!
来源:https://mattferderer.com/NotSupportedException-No-IUserTwoFactorTokenProvider-tuser-named-default-registered
我在更新Identity后得到了相同的错误,并发现这是因为我使用Unity。
看这个问题的解决方案:用Unity注册IAuthenticationManager
下面也是快速参考:
这是我所做的,使Unity与ASP玩得很好。. NET Identity 2.0:
我在
UnityConfig
类的RegisterTypes
方法中添加了以下内容: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());
您可能也有兴趣看看这里:
如何在ASP中实现TokenProvider。. NET Identity 1.1夜间构建?
使用Microsoft.Identity.Owin包
在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"));
}
对于ASP也很有用。. NET框架(带有简单的同步任务):
using Microsoft.Owin.Security.DataProtection;
using Microsoft.Owin.Security;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
...
var userStore = new UserStore<IdentityUser>();
var userManager = new UserManager<IdentityUser>(userStore);
var user = userManager.FindByName(MyUserNameTextBox.Text);
var provider = new DpapiDataProtectionProvider(System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName());
userManager.UserTokenProvider = (IUserTokenProvider<IdentityUser, string>)(new DataProtectorTokenProvider<IdentityUser, string>(provider.Create("UserToken")) as IUserTokenProvider<IdentityUser, string>);
var token = userManager.GeneratePasswordResetToken(user.Id);
var result = userManager.ResetPassword(user.Id, token, MyPasswordTextBox.Text);