109 votes

Aucun IUserTokenProvider n'est enregistré

J'ai récemment mis à jour Asp.Net Identity Core de mon formulaire de candidature 1.0 à 2.0.

Il y a de nouvelles fonctionnalités que je voulais essayer comme GenerateEmailConfirmationToken etc.

J'utilise este comme référence.

Lorsque l'utilisateur essaie de s'enregistrer, j'obtiens une erreur lors de l'exécution de la méthode Post de 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);
}

Dans la ligne

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

Je reçois une erreur disant :

No IUserTokenProvider is registered.

Pour l'instant, je voulais juste voir quel genre de code il génère. Est-ce que je dois modifier mon ApplicationUser qui hérite de IdentityUser classe ?

Ou dois-je modifier quelque chose pour que ces fonctions fonctionnent ?

1 votes

Y a-t-il un moyen de vérifier si un utilisateur existe en se basant sur d'autres champs que l'adresse électronique ? Par exemple, si j'avais deux champs appelés Numéro de client et Code postal pour les utilisateurs qui existeraient déjà dans la base de données afin d'empêcher n'importe qui de s'inscrire

134voto

meziantou Points 2867

Vous devez spécifier un UserTokenProvider pour générer un jeton.

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

Vous devriez également lire cet article : Ajouter l'authentification à deux facteurs à une application en utilisant l'identité ASP.NET .

5 votes

Quels sont "Sample" y "EmailConfirmation" un texte qui peut être n'importe quoi

2 votes

"Sample"=AppName, "EmailConfirmation"=but (comme les noms des paramètres)

5 votes

Oui, mais vous devrez utiliser les mêmes pour générer et valider les jetons.

37voto

pisker Points 218

Dans ASP.NET Core, il est aujourd'hui possible de configurer un service par défaut dans le fichier Startup.cs comme ceci :

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

Il n'est pas nécessaire d'appeler le DpapiDataProtectionProvider ou quelque chose comme ça. DefaultTokenProviders() se chargera de l'appel à GenerateEmailConfirmationToken depuis le UserManager.

22voto

trailmax Points 5164

En plus de la réponse acceptée, je voudrais ajouter que cette approche ne fonctionnera pas dans les sites Web Azure, vous obtiendrez CryptographicException au lieu d'un jeton.

Pour le corriger pour Azure, implémentez votre propre IDataProtector : voir cette réponse

Un peu plus de détails dans blog-post

16voto

Amin Ghaderi Points 109

Ma solution :

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

Mon problème avec ce code est résolu.
Bonne chance les amis.

1 votes

En utilisant Microsoft.Owin.Security.DataProtection ;

0 votes

J'ai dû utiliser DataProtectorTokenProvider<IdentityUser, string> au lieu de <User, string> pour les deux génériques. De même, l'userId dans GeneratePasswordResetToken est la chaîne guidée Id et non le userName ou l'Email.

10voto

Ogglas Points 1

Au cas où quelqu'un d'autre ferait la même erreur que moi. J'ai essayé de créer une fonction comme celle ci-dessous et, bien sûr, l'erreur "No IUserTokenProvider is registered" a disparu. Cependant, dès que j'ai essayé d'utiliser le lien généré par "callbackUrl", j'ai eu l'erreur "Invalid token". Pour que cela fonctionne, vous devez obtenir le UserManager de HttpContext. Si vous utilisez une application ASP.NET MVC 5 standard avec des comptes d'utilisateurs individuels, vous pouvez le faire comme ci-dessous

Un code qui fonctionne :

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

Premier essai qui ne fonctionne pas, No IUserTokenProvider is registered. a disparu mais l'URL créé obtient 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();
     }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X