ไม่มีการลงทะเบียน IUserTokenProvider


102

ฉันเพิ่งอัปเดตAsp.Net Identity Coreแบบฟอร์มใบสมัคร 1.0 เป็น 2.0

มีฟีเจอร์ใหม่ที่อยากลองใช้GenerateEmailConfirmationTokenงาน ฯลฯ

ฉันใช้โปรเจ็กต์นี้เป็นข้อมูลอ้างอิง

เมื่อผู้ใช้พยายามลงทะเบียนฉันได้รับข้อผิดพลาดระหว่างการดำเนินการของวิธีการโพสต์การลงทะเบียน

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
มีวิธีใดบ้างที่คุณสามารถตรวจสอบว่ามีผู้ใช้ตามช่องอื่นนอกเหนือจากที่อยู่อีเมลหรือไม่ ตัวอย่างเช่นถ้าฉันมีสองช่องที่เรียกว่า CustomerNumber และรหัสไปรษณีย์สำหรับผู้ใช้ที่จะมีอยู่แล้วในฐานข้อมูลเพื่อหยุดไม่ให้ใครลงทะเบียน
Jay

คำตอบ:


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"));

นอกจากนี้คุณควรอ่านบทความนี้: การเพิ่มถูก Factor Authentication สองถึงแอพลิเคชันการใช้ ASP.NET เอกลักษณ์


5
คืออะไร"Sample"และ"EmailConfirmation"? ข้อความบางอย่างที่สามารถเป็นอะไรก็ได้?
Cybercop

2
"ตัวอย่าง" = AppName, "EmailConfirmation" = จุดประสงค์ (เช่นชื่อพารามิเตอร์)
meziantou

5
ใช่ แต่คุณจะต้องใช้เหมือนกันในการสร้างและตรวจสอบโทเค็น
meziantou

1
ลิงค์ก็โอเค คุณใส่รหัสนี้ที่คุณเริ่มต้นUserManager
meziantou

ทำให้ 'ไม่สามารถโหลดชนิด' System.Security.Cryptography.DpapiDataProtector 'จากการประกอบใน. netcore
TAHA SULTAN TEMURI

25

ใน ASP.NET Core ปัจจุบันสามารถกำหนดค่าบริการเริ่มต้นใน Startup.cs ได้ดังนี้:

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

ไม่จำเป็นต้องเรียกDpapiDataProtectionProviderหรืออะไรแบบนั้น DefaultTokenProviders () จะดูแลการเรียกใช้ GenerateEmailConfirmationToken จาก UserManager


21

นอกเหนือจากคำตอบที่ได้รับการยอมรับแล้วฉันต้องการเพิ่มว่าวิธีนี้จะใช้ไม่ได้ใน Azure Web-Sites คุณจะได้รับ CryptographicException แทนโทเค็น

หากต้องการแก้ไขสำหรับ Azure ให้ใช้ IDataProtector ของคุณเอง: ดูคำตอบนี้

รายละเอียดเพิ่มเติมเล็กน้อยในบล็อกโพสต์


13

วิธีแก้ปัญหาของฉัน:

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

ปัญหาของฉันเกี่ยวกับรหัสนี้ได้รับการแก้ไขแล้ว
ขอให้โชคดีนะเพื่อน


ใช้ Microsoft.Owin.Security.DataProtection;
Amin Ghaderi

ฉันต้องใช้ DataProtectorTokenProvider <IdentityUser, string> แทน <User, string> สำหรับทั้งสองทั่วไป นอกจากนี้ userId ใน GeneratePasswordResetToken ยังเป็นรหัสสตริง guid ไม่ใช่ชื่อผู้ใช้หรืออีเมล
Dan Randolph

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

ตาม pisker ด้านบน

ใน startup.cs คุณสามารถใช้ได้

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

ใน. net core 2.0 คุณอาจต้องเพิ่มใน startup.cs:

using Microsoft.AspNetCore.Identity;

สิ่งนี้ใช้ได้ดีสำหรับฉัน


1
ฉันคิดว่าเป็นสิ่งสำคัญที่ต้องจำไว้ว่านี่เป็นโซลูชัน Asp .NET Core ซึ่งจะไม่ทำงานกับ Asp .NET Framework
Machado

4

ขณะแก้ไขไฟล์ Identity ของ. NET Core ฉันพบข้อผิดพลาดนี้:

NotSupportedException: ไม่มีการลงทะเบียน IUserTwoFactorTokenProvider ที่ชื่อ 'Default'

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

ฉันได้รับข้อผิดพลาดเดียวกันหลังจากอัปเดต 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());

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"));
        }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.