Không có IUserTokenProvider được đăng ký


101

Gần đây tôi đã cập nhật Asp.Net Identity Coređơn đăng ký của mình từ 1.0 đến 2.0.

Có những tính năng mới mà tôi muốn thử GenerateEmailConfirmationToken, v.v.

Tôi đang sử dụng dự án này như một tài liệu tham khảo.

Khi người dùng cố gắng đăng ký, tôi gặp lỗi trong quá trình thực hiện phương thức Đăng ký

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

Trong dòng

 var code = _userManager.GenerateEmailConfirmationToken(user.Id);

Tôi gặp lỗi khi nói:

No IUserTokenProvider is registered.

Hiện tại, tôi chỉ muốn xem nó tạo ra loại mã nào. Có một số thay đổi tôi cần thực hiện đối với ApplicationUserlớp kế thừa từ IdentityUserlớp của mình không?

Hoặc có điều gì đó tôi cần thay đổi để các chức năng đó hoạt động?


1
Có cách nào bạn có thể kiểm tra xem người dùng có tồn tại hay không dựa trên các trường khác ngoài địa chỉ email? Ví dụ nếu tôi đã có hai lĩnh vực được gọi là CustomerNumber và Mã bưu cho những người dùng đã có thể sẵn tồn tại trong cơ sở dữ liệu để ngăn chặn bất cứ ai từ đăng ký
Jay

Câu trả lời:


127

Bạn phải chỉ định một UserTokenProviderđể tạo mã thông báo.

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

Bạn cũng nên đọc bài viết này: Thêm xác thực hai yếu tố vào ứng dụng bằng ASP.NET Identity .


5
là gì "Sample"và là "EmailConfirmation"gì? một số văn bản có thể là bất cứ điều gì?
Cybercop

2
"Sample" = AppName, "EmailConfirmation" = mục đích (như tên thông số)
meziantou

5
Có, nhưng bạn sẽ phải sử dụng tương tự để tạo và xác thực mã thông báo
meziantou

1
Liên kết là OK. Bạn đặt mã này ở nơi bạn khởi tạoUserManager
meziantou

nguyên nhân này 'Không thể tải kiểu 'System.Security.Cryptography.DpapiDataProtector' từ lắp ráp trong .netcore
Taha SULTAN TEMURI

25

Trong ASP.NET Core ngày nay có thể định cấu hình một dịch vụ mặc định trong Startup.cs như sau:

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

Không cần thiết phải gọi DpapiDataProtectionProviderhoặc bất cứ điều gì tương tự. DefaultTokenProviders () sẽ xử lý lệnh gọi GenerateEmailConfirmationToken từ UserManager.


21

Ngoài câu trả lời được chấp nhận, tôi muốn nói thêm rằng cách tiếp cận này sẽ không hoạt động trong Azure Web-Sites, bạn sẽ nhận được CryptographicException thay vì mã thông báo.

Để sửa lỗi cho Azure, hãy triển khai IDataProtector của riêng bạn: xem câu trả lời này

Chi tiết hơn một chút trong bài đăng trên blog


13

Giải pháp của tôi :

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

Vấn đề của tôi với mã này đã được giải quyết.
Chúc các bạn may mắn.


sử dụng Microsoft.Owin.Security.DataProtection;
Amin Ghaderi

Tôi đã phải sử dụng DataProtectorTokenProvider <IdentityUser, string> thay vì <User, string> cho cả hai loại chung. Ngoài ra, userId trong GeneratePasswordResetToken là Id chuỗi hướng dẫn chứ không phải userName hoặc Email.
Dan Randolph

7

Trong trường hợp bất kỳ ai khác mắc lỗi tương tự như tôi đã làm. Tôi đã thử tạo một hàm như bên dưới và chắc chắn là có lỗi "Không có IUserTokenProvider được đăng ký." đã ra đi. Tuy nhiên, ngay sau khi tôi cố gắng sử dụng liên kết được tạo từ "callbackUrl", tôi đã gặp lỗi "Mã thông báo không hợp lệ". Để nó hoạt động, bạn cần lấy UserManager HttpContext. Nếu bạn đang sử dụng ứng dụng ASP.NET MVC 5 tiêu chuẩn với các tài khoản người dùng cá nhân, bạn có thể thực hiện như bên dưới ..

Mã hoạt động:

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();
     }

Lần đầu tiên thử, điều đó không hoạt động, No IUserTokenProvider is registered.đã biến mất nhưng URL được tạo vẫn nhận được 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

Theo pisker ở trên

Trong startup.cs bạn có thể sử dụng

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

Trong .net core 2.0, bạn có thể cần thêm vào startup.cs:

using Microsoft.AspNetCore.Identity;

Điều này làm việc tốt cho tôi.


1
Tôi nghĩ điều quan trọng cần nhớ rằng đây là giải pháp Asp .NET Core, nó sẽ không hoạt động với Asp .NET Framework.
Machado

3

Trong khi sửa đổi tệp Identity của .NET Core, tôi đã tình cờ gặp lỗi này:

NotSupportedException: Không có IUserTwoFactorTokenProvider có tên 'Mặc định' được đăng ký.

Các

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

hàm không thể tạo mã thông báo vì không có nhà cung cấp nào khả dụng khi đăng ký người dùng mới. Lỗi này có một cách khắc phục dễ dàng!

Nếu bạn giống tôi, bạn đã thay đổi AddDefaultIdentitytrong Startup.cstệp thành AddIdentity. Tôi muốn triển khai người dùng của riêng mình được kế thừa từ người dùng cơ sở. Bằng cách này, tôi đã mất các nhà cung cấp mã thông báo mặc định. Cách khắc phục là thêm chúng trở lại với AddDefaultTokenProviders().

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

Sau khi sửa chữa đó, mọi thứ đã hoạt động trở lại!

nguồn: https://mattferderer.com/NotSupportedException-No-IUserTwoFactorTokenProvider-tuser-name-default-registered


1

Tôi gặp lỗi tương tự sau khi cập nhật Identity và nhận thấy rằng đó là do tôi đang sử dụng Unity.

Xem chuỗi câu hỏi này về giải pháp: Đăng ký IAuthenticationManager với Unity

Cũng dưới đây để tham khảo nhanh:

Đây là những gì tôi đã làm để làm cho Unity chơi tốt với ASP.NET Identity 2.0:

Tôi đã thêm phần sau vào RegisterTypesphương thức trong UnityConfiglớp:

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
Tôi đã làm theo điều này, nhưng nó không hoạt động (vì GeneratePasswordResetToken- nhưng gặp cùng một lỗi "Không có IUserTokenProvider được đăng ký"). Sau khi thêm container.RegisterType<ApplicationUserManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()));vào UnityConfig.cs, nó đã hoạt động.


0

trong IdentityConfig.cs, Thêm tùy chọn hai yếu tố của bạn:

        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"));
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.