106

我最近更新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.

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

或者我需要改变什么才能让这些功能正常工作?

4

11 回答 11

131

您必须指定 aUserTokenProvider才能生成令牌。

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 身份向应用程序添加两因素身份验证

于 2014-03-25T13:03:33.353 回答
34

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

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

没有必要调用DpapiDataProtectionProvider或类似的东西。DefaultTokenProviders() 将负责从 UserManager 调用 GenerateEmailConfirmationToken。

于 2017-02-23T15:33:52.877 回答
22

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

要为 Azure 修复它,请实现您自己的 IDataProtector:请参阅此答案

博客文章中的详细信息

于 2014-06-21T00:19:13.360 回答
15

我的解决方案:

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

我的代码问题解决了。
祝朋友好运。

于 2014-11-12T01:42:16.140 回答
9

以防其他人犯和我一样的错误。我尝试制作一个类似下面的函数,并且确实出现了错误“未注册 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();
     }
于 2015-12-29T16:59:11.190 回答
6

根据上面的pisker

在 startup.cs 你可以使用

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

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

using Microsoft.AspNetCore.Identity;

这对我来说很好。

于 2017-08-22T14:48:38.630 回答
4

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

NotSupportedException:没有注册名为“默认”的 IUserTwoFactorTokenProvider。

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

函数无法生成令牌,因为在注册新用户时没有可用的提供程序。这个错误有一个简单的解决方法!

如果你像我一样,你AddDefaultIdentityStartup.cs文件中更改为AddIdentity. 我想实现从基本用户继承的我自己的用户。通过这样做,我丢失了默认令牌提供程序。解决方法是用AddDefaultTokenProviders().

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

修复后,一切都恢复正常了!

来源:https ://mattferderer.com/NotSupportedException-No-IUserTwoFactorTokenProvider-tuser-named-default-registered

于 2019-07-13T08:31:03.880 回答
1

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

在解决方案中查看这个问题线程: Register IAuthenticationManager with 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());
于 2015-02-03T17:32:09.037 回答
0

您可能也有兴趣在这里查看:
如何在 ASP.NET Identity 1.1 nightly build 中实现 TokenProvider?
使用 Microsoft.Identity.Owin 包中的默认令牌提供程序实现

于 2014-12-11T09:31:04.197 回答
0

它对 ASP.NET Framework 也很有用(带有简单的同步任务):

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);
于 2021-12-30T09:29:22.373 回答
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"));
        }
于 2018-07-28T10:17:05.397 回答