locked
No IUserTokenProvider is registered, when sending a reset password request RRS feed

  • Question

  • User-1256377279 posted

    Hi Guys,

    Could anyone one me with Error "No IUserTokenProvider is registered" using ASP.NET Identity, Basically i have to send a user a reset password link. Below is my code

    Reset.aspx

    protected void btnSend_Click(object sender, EventArgs e)
        {
            if(IsValid)
            {
                //var manager = new UserManager();
                //ApplicationUser user = manager.FindByEmail(Email.Text);
    
                //string code = manager.GeneratePasswordResetToken(user.Id);
    
              // var manager =  Context.GetOwinContext().GetUserManager<ApplicationUserManager>();           
    
                var manager = new UserManager();
                ApplicationUser user = manager.FindByEmail(Email.Text);
    
                string code = manager.GeneratePasswordResetToken(user.Id); Error
                //string callbackUrl = IdentityHelper.GetResetPasswordRedirectUrl(code, Request);
                //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
               // return View();
            }
        }

    Identity.CS

        public class ApplicationUser : IdentityUser
        {
            //New Fields in user table
            public string LegacyPasswordHash { get; set; }
            //public string FirstName { get; set; }
            //public string LastName { get; set; }
       
        }
    
        public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
        {
            public ApplicationDbContext()
                : base("DefaultConnection")
            {
                //Disable Automatic database updates for Entity Framework
                Database.SetInitializer<ApplicationDbContext>(null);        
            }
    
        }
    
        #region Helpers
        public class UserManager : UserManager<ApplicationUser>
        {
            public UserManager()
                : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
            { }
        }
    
        public class RoleManager : RoleManager<IdentityRole>
        {
            public RoleManager()
                : base(new RoleStore<IdentityRole>(new ApplicationDbContext()))
            { }
        }
        #endregion
        public static class IdentityHelper
        {
            // Used for XSRF when linking external logins
            public const string XsrfKey = "XsrfId";
    
            public static void SignIn(UserManager manager, ApplicationUser user, bool isPersistent)
            {
                IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
                var identity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
                authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
            }
    
            public const string ProviderNameKey = "providerName";
            public static string GetProviderNameFromRequest(HttpRequest request)
            {
                return request[ProviderNameKey];
            }
    
            public const string CodeKey = "code";
            public static string GetCodeFromRequest(HttpRequest request)
            {
                return request.QueryString[CodeKey];
            }
    
            public const string UserIdKey = "userId";
            public static string GetUserIdFromRequest(HttpRequest request)
            {
                return HttpUtility.UrlDecode(request.QueryString[UserIdKey]);
            }
    
            public static string GetExternalLoginRedirectUrl(string accountProvider)
            {
                return "/Account/RegisterExternalLogin?" + ProviderNameKey + "=" + accountProvider;
            }
    
            private static bool IsLocalUrl(string url)
            {
                return !string.IsNullOrEmpty(url) && ((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) || (url.Length > 1 && url[0] == '~' && url[1] == '/'));
            }
    
            public static void RedirectToReturnUrl(string returnUrl, HttpResponse response)
            {
                if (!String.IsNullOrEmpty(returnUrl) && IsLocalUrl(returnUrl))
                {
                    response.Redirect(returnUrl);
                }
                else
                {
                    response.Redirect("~/");
                }
            }
    
            public static string GetResetPasswordRedirectUrl(string code, HttpRequest request)
            {
                var absoluteUri = "/Account/ResetPassword?" + CodeKey + "=" + HttpUtility.UrlEncode(code);
                return new Uri(request.Url, absoluteUri).AbsoluteUri.ToString();
            }
        }

    I have removed Identity.Config and Identity.Models in to seperate project and Name as Identity.cs

    Thanks,

    Shabbir

    Tuesday, February 2, 2016 11:38 AM

All replies

  • User614698185 posted

    Hi Shabbir,

    You have to specify a UserTokenProvider to generate a token:

    using Microsoft.Owin.Security.DataProtection;
    using Microsoft.AspNet.Identity.Owin;
    // ...
    
    var provider = new DpapiDataProtectionProvider("Sample");
    var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
    userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"));

    Please see: https://blogs.msdn.microsoft.com/webdev/2014/02/18/adding-two-factor-authentication-to-an-application-using-asp-net-identity/

    Best Regards,

    Candice Zhou

    Wednesday, February 3, 2016 2:53 AM
  • User-1256377279 posted

    Hi Candice,

    Can you let me know where to update your code to get it work.

    Many Thanks,

    Shabbir

    Wednesday, February 3, 2016 9:25 AM
  • User614698185 posted

    Hi Shabbir,

    I have removed Identity.Config and Identity.Models in to seperate project and Name as Identity.cs

    So, you could put the code in Identity.cs file.

    Best Regards,

    Candice Zhou

    Wednesday, February 3, 2016 10:06 AM
  • User-1256377279 posted

    Hi Candice

    I have add as below but still display as No IUserTokenProvider is registered

    public class UserManager : UserManager<ApplicationUser>
        {
            public UserManager()
                : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
            {
                var provider = new DpapiDataProtectionProvider("Sample");
                var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
                userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"));
            }
        }

    Thanks,

    Shabbir

    Wednesday, February 3, 2016 11:14 AM
  • User614698185 posted

    Hi Shabbir,

    IUserTokenProvider by default is inserted by OWIN, but when you resolve UserManager from your code, component that provides IUserTokenProvider is not available and this component is not initialised.

    You'll have to assign token provider to a global static variable when it is available and then re-use it in UserManager constructor:

    http://stackoverflow.com/questions/27471363/no-iusertokenprovider-is-registered-when-using-structuremap-dependency-injecti

    Best Regards,

    Candice Zhou

    Friday, February 5, 2016 9:45 AM
  • User-1256377279 posted

    Thanks Candice

    I tried your link but i am getting an error as 

    Error 2 Cannot implicitly convert type 'Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<TestLogin.ApplicationUser,System.Guid>' to 'Microsoft.AspNet.Identity.IUserTokenProvider<TestLogin.ApplicationUser,string>'. An explicit conversion exists (are you missing a cast?) c:\inetpub\wwwroot\testlogin\app_code\identitymodels.cs 48 41 http://localhost/TestLogin/

      var dataProtectorProvider = Startup.DataProtectionProvider;
                var dataProtector = dataProtectorProvider.Create("My Asp.Net Identity");
                manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser,Guid>(dataProtector); //Error

    Please could you help me with this

    Thanks,

    Shabbir

    Friday, February 12, 2016 11:02 AM
  • User614698185 posted

    Hi Shabbir,

    Based on your error, it occurs when you assign a variable of one type to a variable of a different type.

    In the IdentityConfig.cs file, we find an ApplicationUserManager class, which contains code commonly called by our application to, well, manage users and behaviors. we will replace the existing code with the following, which essentially expresses ApplicationUserManager in terms of integer keys, and our new custom UserStore. If you look closely, we have added an int type argument to many of the method calls.

    var dataProtectionProvider = options.DataProtectionProvider;
      
    if (dataProtectionProvider != null)
    {
         // *** ADD INT TYPE ARGUMENT TO METHOD CALL:
         manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(
                        dataProtectionProvider.Create("ASP.NET Identity"));
    }

    Please see: http://www.codeproject.com/Articles/798001/ASP-NET-Identity-Extending-Identity-Models-and-Usi

    Best Regards,

    Candice Zhou

    Friday, February 19, 2016 8:46 AM