Tidak ada IUserTokenProvider yang terdaftar

101

Saya baru saja memperbarui Asp.Net Identity Coreformulir aplikasi saya 1.0 ke 2.0.

Ada fitur baru yang ingin saya coba GenerateEmailConfirmationToken, dll.

Saya menggunakan proyek ini sebagai referensi.

Ketika pengguna mencoba untuk mendaftar, saya mendapatkan kesalahan selama eksekusi metode Post Register

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

Di antrean

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

Saya mendapatkan kesalahan yang mengatakan:

No IUserTokenProvider is registered.

Untuk saat ini, saya hanya ingin melihat jenis kode yang dihasilkannya. Apakah ada perubahan yang perlu saya lakukan pada ApplicationUserkelas saya yang diwarisi dari IdentityUserkelas?

Atau adakah sesuatu yang perlu saya ubah agar fungsi tersebut berfungsi?

Cybercop
sumber
1
Adakah cara agar Anda dapat memeriksa apakah ada pengguna berdasarkan bidang selain alamat email? Misalnya jika saya memiliki dua bidang yang disebut NomorPelanggan dan Kode Pos untuk pengguna yang sudah ada sebelumnya di database untuk menghentikan sembarang orang dari mendaftar
Jay

Jawaban:

127

Anda harus menentukan UserTokenProvideruntuk menghasilkan token.

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

Anda juga harus membaca artikel ini: Menambahkan Otentikasi Dua Faktor ke Aplikasi yang Menggunakan Identitas ASP.NET .

meziantou
sumber
5
apa "Sample"dan "EmailConfirmation"? beberapa teks yang bisa apa saja?
Cybercop
2
"Sample" = AppName, "EmailConfirmation" = purpose (seperti nama parameter)
meziantou
5
Ya, tetapi Anda harus menggunakan hal yang sama untuk menghasilkan dan memvalidasi token
meziantou
1
Tautannya oke. Anda meletakkan kode ini di tempat Anda menginisialisasiUserManager
meziantou
ini menyebabkan 'Tidak dapat memuat jenis' System.Security.Cryptography.DpapiDataProtector 'dari perakitan di .netcore
TAHA SULTAN TEMURI
25

Di ASP.NET Core, saat ini dimungkinkan untuk mengkonfigurasi layanan default di Startup.cs seperti ini:

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

Tidak perlu memanggil DpapiDataProtectionProvideratau apapun seperti itu. DefaultTokenProviders () akan menangani panggilan ke GenerateEmailConfirmationToken dari UserManager.

pisker
sumber
21

Selain jawaban yang diterima, saya ingin menambahkan bahwa pendekatan ini tidak akan berfungsi di Situs Web Azure, Anda akan mendapatkan CryptographicException, bukan token.

Untuk memperbaikinya untuk Azure, terapkan IDataProtector Anda sendiri: lihat jawaban ini

Sedikit lebih detail di posting blog

trailmax
sumber
13

Solusi saya:

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

Masalah saya dengan kode ini terpecahkan.
Semoga beruntung teman.

Amin Ghaderi
sumber
menggunakan Microsoft.Owin.Security.DataProtection;
Amin Ghaderi
Saya harus menggunakan DataProtectorTokenProvider <IdentityUser, string> bukannya <User, string> untuk kedua obat generik. Juga userId di GeneratePasswordResetToken adalah Id string guid dan bukan userName atau Email.
Dan Randolph
7

Jika ada orang lain yang melakukan kesalahan yang sama seperti yang saya lakukan. Saya mencoba membuat fungsi seperti di bawah ini dan cukup yakin kesalahan "Tidak ada IUserTokenProvider terdaftar." telah pergi. Namun begitu saya mencoba menggunakan tautan yang dihasilkan dari "callbackUrl", saya mendapat pesan kesalahan "Token tidak valid." Agar bisa bekerja, Anda perlu mendapatkan HttpContext UserManager. Jika Anda menggunakan aplikasi ASP.NET MVC 5 standar dengan akun pengguna individu, Anda dapat melakukannya seperti di bawah ini ..

Kode yang berfungsi:

public ActionResult Index()
     {
         //Code to create ResetPassword URL
         var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
         var user = userManager.FindByName("[email protected]");
         string code = userManager.GeneratePasswordResetToken(user.Id);
         var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
         return View();
     }

Percobaan pertama yang tidak berhasil, No IUserTokenProvider is registered.hilang tetapi URL yang dibuat mendapat 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("[email protected]");
             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();
     }
Ogglas
sumber
5

Sesuai pisker di atas

Di startup.cs Anda dapat menggunakan

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

Di .net core 2.0 Anda mungkin perlu menambahkan ke startup.cs:

using Microsoft.AspNetCore.Identity;

Ini bekerja dengan baik untuk saya.

ScottC
sumber
1
Saya pikir penting untuk diingat bahwa ini adalah solusi Asp .NET Core, itu tidak akan berfungsi dengan Asp .NET Framework.
Machado
3

Saat memodifikasi file Identitas .NET Core, saya menemukan kesalahan ini:

NotSupportedException: Tidak ada IUserTwoFactorTokenProvider bernama 'Default' yang terdaftar.

Itu

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

fungsi tidak dapat menghasilkan token karena tidak ada penyedia yang tersedia saat mendaftarkan pengguna baru. Kesalahan ini memiliki perbaikan yang mudah!

Jika Anda seperti saya, Anda berubah AddDefaultIdentitydalam Startup.csfile AddIdentity. Saya ingin menerapkan pengguna saya sendiri yang diwarisi dari pengguna dasar. Dengan melakukan ini saya kehilangan penyedia token default. Perbaikannya adalah menambahkannya kembali AddDefaultTokenProviders().

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

Setelah perbaikan itu, semuanya berfungsi kembali!

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

Yawar Ali
sumber
1

Saya mendapat kesalahan yang sama setelah memperbarui Identitas, dan ternyata itu karena saya menggunakan Unity.

Lihat utas pertanyaan ini tentang solusi: Daftarkan IAuthenticationManager dengan Unity

Juga di bawah untuk referensi cepat:

Inilah yang saya lakukan untuk membuat Unity bermain bagus dengan ASP.NET Identity 2.0:

Saya menambahkan yang berikut ke RegisterTypesmetode di UnityConfigkelas:

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());
rampok
sumber
1
Saya mengikuti ini, tetapi tidak berhasil (untuk GeneratePasswordResetToken- tetapi mendapat kesalahan yang sama dari "Tidak ada IUserTokenProvider terdaftar"). Setelah menambahkan container.RegisterType<ApplicationUserManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()));untuk UnityConfig.cs, itu bekerja.
0

di IdentityConfig.cs, Tambahkan opsi dua faktor Anda:

        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"));
        }
Mohammad Reza Mrg
sumber