Es ist kein IUserTokenProvider registriert

100

Ich habe kürzlich Asp.Net Identity Coremein Antragsformular 1.0 auf 2.0 aktualisiert .

Es gibt neue Funktionen, die ich ausprobieren wollte GenerateEmailConfirmationToken, usw.

Ich benutze dieses Projekt als Referenz.

Wenn der Benutzer versucht, sich zu registrieren, wird während der Ausführung der Post-Registrierungsmethode ein Fehler angezeigt

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

In der Schlange

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

Ich erhalte die Fehlermeldung:

No IUserTokenProvider is registered.

Im Moment wollte ich nur sehen, welche Art von Code generiert wird. Muss ich einige Änderungen an meiner ApplicationUserKlasse vornehmen , die von der IdentityUserKlasse erbt ?

Oder muss ich etwas ändern, damit diese Funktion funktioniert?

Cybercop
quelle
1
Gibt es eine Möglichkeit, anhand anderer Felder als der E-Mail-Adresse zu überprüfen, ob ein Benutzer vorhanden ist? Zum Beispiel, wenn ich zwei Felder mit dem Namen CustomerNumber und Postcode für Benutzer hätte, die bereits in der Datenbank vorhanden wären, um zu verhindern, dass sich jemand registriert
Jay,

Antworten:

126

Sie müssen a angeben UserTokenProvider, um ein Token zu generieren.

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

Sie sollten auch diesen Artikel lesen: Hinzufügen einer Zwei-Faktor-Authentifizierung zu einer Anwendung mit ASP.NET-Identität .

Meziantou
quelle
5
was sind "Sample"und "EmailConfirmation"? irgendein Text, der alles sein kann?
Cybercop
2
"Sample" = AppName, "EmailConfirmation" = Zweck (wie die Parameternamen)
Meziantou
5
Ja, aber Sie müssen das gleiche für das Generieren und Validieren von Token verwenden
Meziantou
1
Der Link ist OK. Sie setzen diesen Code, wo Sie dieUserManager
Meziantou
Dies führt dazu, dass der Typ 'System.Security.Cryptography.DpapiDataProtector' von der Assembly in .netcore
TAHA SULTAN TEMURI
25

In ASP.NET Core ist es heutzutage möglich, einen Standarddienst in Startup.cs wie folgt zu konfigurieren:

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

Es besteht keine Notwendigkeit, das DpapiDataProtectionProvideroder so etwas anzurufen . Die DefaultTokenProviders () kümmern sich um den Aufruf von GenerateEmailConfirmationToken aus dem UserManager.

Pisker
quelle
21

Zusätzlich zu der akzeptierten Antwort möchte ich hinzufügen, dass dieser Ansatz auf Azure-Websites nicht funktioniert. Sie erhalten CryptographicException anstelle eines Tokens.

Implementieren Sie Ihren eigenen IDataProtector, um das Problem für Azure zu beheben. Siehe diese Antwort

Etwas mehr Details im Blog-Beitrag

Trailmax
quelle
13

Meine Lösung :

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

Mein Problem mit diesem Code wurde gelöst.
Viel Glück Freunde.

Amin Ghaderi
quelle
Verwenden von Microsoft.Owin.Security.DataProtection;
Amin Ghaderi
Ich musste DataProtectorTokenProvider <IdentityUser, string> anstelle von <User, string> für beide Generika verwenden. Außerdem ist die Benutzer-ID in GeneratePasswordResetToken die Guid-Zeichenfolgen-ID und nicht der Benutzername oder die E-Mail-Adresse.
Dan Randolph
7

Für den Fall, dass jemand den gleichen Fehler macht wie ich. Ich habe versucht, eine Funktion wie die folgende zu erstellen, und zwar den Fehler "Kein IUserTokenProvider ist registriert." war weg. Sobald ich jedoch versuchte, den von "callbackUrl" generierten Link zu verwenden, wurde der Fehler "Ungültiges Token" angezeigt. Damit es funktioniert, müssen Sie den HttpContext UserManager herunterladen. Wenn Sie eine Standardanwendung von ASP.NET MVC 5 mit einzelnen Benutzerkonten verwenden, können Sie dies wie folgt tun.

Code, der funktioniert:

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

Erster Versuch, der nicht funktioniert, No IUserTokenProvider is registered.ist weg, aber die erstellte URL wird abgerufen 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
quelle
5

Wie oben beschrieben

In startup.cs können Sie verwenden

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

In .net Core 2.0 müssen Sie möglicherweise die Datei startup.cs hinzufügen:

using Microsoft.AspNetCore.Identity;

Das hat bei mir gut funktioniert.

ScottC
quelle
1
Ich denke, das ist wichtig zu bedenken, dass dies eine Asp .NET Core-Lösung ist, die mit Asp .NET Framework nicht funktioniert.
Machado
2

Beim Ändern der Identitätsdateien von .NET Core bin ich auf diesen Fehler gestoßen:

NotSupportedException: Es ist kein IUserTwoFactorTokenProvider mit dem Namen 'Default' registriert.

Das

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

Die Funktion konnte kein Token generieren, da bei der Registrierung eines neuen Benutzers kein Anbieter verfügbar war. Dieser Fehler lässt sich jedoch leicht beheben!

Wenn Sie wie ich sind, haben Sie AddDefaultIdentityin der Startup.csDatei zu geändert AddIdentity. Ich wollte meinen eigenen Benutzer implementieren, der vom Basisbenutzer geerbt hat. Dadurch habe ich die Standard-Token-Anbieter verloren. Die Lösung bestand darin, sie wieder hinzuzufügen AddDefaultTokenProviders().

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

Nach diesem Fix hat alles wieder funktioniert!

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

Yawar Ali
quelle
1

Ich habe nach dem Aktualisieren von Identity den gleichen Fehler erhalten und festgestellt, dass ich Unity verwendet habe.

Weitere Informationen finden Sie in diesem Fragethread zur Lösung: Registrieren Sie IAuthenticationManager bei Unity

Auch unten als Kurzreferenz:

Folgendes habe ich getan, damit Unity mit ASP.NET Identity 2.0 gut funktioniert:

Ich habe der RegisterTypesMethode in der UnityConfigKlasse Folgendes hinzugefügt :

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());
rauben
quelle
1
Ich habe dies befolgt, aber es hat nicht funktioniert (für GeneratePasswordResetToken- aber es wurde der gleiche Fehler "Kein IUserTokenProvider ist registriert" angezeigt). Nach dem Hinzufügen container.RegisterType<ApplicationUserManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()));zu UnityConfig.cshat es funktioniert.
0

Fügen Sie in IdentityConfig.cs Ihre Option für zwei Faktoren hinzu:

        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
quelle