没有注册IUserTokenProvider


101

我最近将Asp.Net Identity Core申请表1.0 更新为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.

现在,我只想看看它生成什么样的代码。我需要对ApplicationUserIdentityUser类继承的类进行一些更改吗?

还是我需要更改某些功能才能使这些功能正常工作?


1
有什么方法可以根据电子邮件地址以外的其他字段检查用户是否存在?例如,如果我有两个名为CustomerNumber和Postcode的字段供那些已经存在于数据库中的用户阻止任何人注册
Jay

Answers:


127

您必须指定一个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 Identity向应用程序添加两因素身份验证


5
什么是"Sample""EmailConfirmation"?一些文本可以是什么?
Cyber​​cop

2
“ Sample” = AppName,“ EmailConfirmation” =用途(如参数名称)
meziantou 2014年

5
是的,但是您必须使用相同的令牌来生成和验证令牌
meziantou 2014年

1
链接确定。您将这段代码放在初始化UserManager
meziantou 2014年

这会导致“无法从.netcore中的程序集加载类型'System.Security.Cryptography.DpapiDataProtector”
TAHA SULTAN TEMURI,

25

在ASP.NET Core中,如今可以像这样在Startup.cs中配置默认​​服务:

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

无需调用DpapiDataProtectionProvider或类似的名称。DefaultTokenProviders()将负责从UserManager调用GenerateEmailConfirmationToken。



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>。此外,GeneratePasswordResetToken中的userId是引导字符串Id,而不是userName或Email。
丹·伦道夫

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。
马查多

2

在修改.NET Core的身份文件时,我偶然发现了此错误:

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


1

更新身份后出现相同的错误,发现那是因为我在使用Unity。

请参阅解决方案中的以下问题线程: 向Unity注册IAuthenticationManager

同样在下面以供快速参考:

这是我为使Unity与ASP.NET Identity 2.0兼容而做的工作:

RegisterTypesUnityConfig类的方法中添加了以下内容:

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中,添加您的twofactor选项:

        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"));
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.