没有注册IUserTokenProvider

时间:2014-03-25 09:14:18

标签: c# asp.net asp.net-identity-2

我最近更新了申请表格1.0到2.0的Asp.Net Identity Core

我想尝试一些新功能,例如GenerateEmailConfirmationToken等。

我使用this项目作为参考。

当用户尝试注册时,我在执行寄存器的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类进行一些更改吗?

或者有什么我需要改变以使这些功能起作用吗?

10 个答案:

答案 0 :(得分:120)

您必须指定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"));

您还应该阅读这篇文章:Adding Two Factor Authentication to an Application Using ASP.NET Identity

答案 1 :(得分:20)

除了接受的答案之外,我还想补充一点,这种方法在Azure网站中不起作用,您将获得CryptographicException而不是令牌。

要为Azure修复此问题,请实施您自己的IDataProtector:see this answer

blog-post

中的更多细节

答案 2 :(得分:20)

在ASP.NET Core中,现在可以在Startup.cs中配置默认​​服务,如下所示:

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

无需拨打DpapiDataProtectionProvider或类似的内容。 DefaultTokenProviders()将负责从UserManager调用GenerateEmailConfirmationToken。

答案 3 :(得分:11)

我的解决方案:

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

我解决了这段代码的问题。
祝你好运。

答案 4 :(得分:7)

如果其他人犯了同样的错误。我尝试创建一个类似下面的函数,确定错误&#34;没有注册IUserTokenProvider。&#34;走了。但是,只要我尝试使用&#34; callbackUrl&#34;生成的链接我收到错误&#34;无效令牌。&#34;为了使它工作,您需要获取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.已消失,但创建的网址为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 :(得分:5)

按照上面的pisker

在startup.cs中,您可以使用

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

在.net core 2.0中,您可能需要添加到startup.cs:

using Microsoft.AspNetCore.Identity;

这对我来说很好。

答案 6 :(得分:0)

你可能也有兴趣看这里:
How to implement a TokenProvider in ASP.NET Identity 1.1 nightly build?
使用Microsoft.Identity.Owin包中的默认令牌提供程序实现

答案 7 :(得分:0)

更新Identity后我遇到了同样的错误,发现这是因为我使用的是Unity。

在解决方案上查看此问题主题: Register IAuthenticationManager with Unity

以下是快速参考:

  

以下是我使用Unity Identity 2.0实现Unity的好处:

     

我将以下内容添加到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());

答案 8 :(得分: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"));
        }

答案 9 :(得分:0)

在修改.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