ASP.NET Identity: use GeneratePasswordResetToken on Azure website

白昼怎懂夜的黑 提交于 2019-12-06 04:11:00

问题


I have my web application deployed on Microsoft Azure. However when I want to generate a PasswordResetToken with:

var token = await _userManager.GeneratePasswordResetTokenAsync(user.Id);

I get the following error:

System.Security.Cryptography.CryptographicException: The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

How do I get this to work on Azure?

Or is there an other way to reset a password without knowing the old password?

This is my UserManager class. Mabey there is an error in it.

public class ApplicationUserManager : UserManager<ApplicationIdentityUser>
{
    private static IUnitOfWork _unitOfWork;
    private readonly IRepository<ApplicationIdentityUser> _userRepository;


    public ApplicationUserManager(IUserStore<ApplicationIdentityUser> store, IRepository<ApplicationIdentityUser> userRepository)
        : base(store)
    {
        if (userRepository == null) throw new ArgumentNullException("userRepository");

        _userRepository = userRepository;

        if (bool.Parse(ConfigurationManager.AppSettings["RunningInAzure"]))
            UserTokenProvider = new EmailTokenProvider<ApplicationIdentityUser, string>();
        else
        {
            var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("TopRijden");
            UserTokenProvider = new DataProtectorTokenProvider<ApplicationIdentityUser, string>(provider.Create("Password Reset"));
        }
    }


    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        if (options == null) throw new ArgumentNullException("options");
        if (context == null) throw new ArgumentNullException("context");

        try
        {
            _unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();
            var userRepository = ObjectFactory.GetInstance<IRepository<ApplicationIdentityUser>>();

            var manager = new ApplicationUserManager(new UserStore<ApplicationIdentityUser>(_unitOfWork.Session), userRepository);

            // Configure validation logic for usernames
            manager.UserValidator = new UserValidator<ApplicationIdentityUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };

            // Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = true,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };

            // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
            // You can write your own provider and plug in here.
            manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationIdentityUser>
            {
                MessageFormat = "Your security code is: {0}"
            });

            manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationIdentityUser>
            {
                Subject = "Security Code",
                BodyFormat = "Your security code is: {0}"
            });

            var dataProtectionProvider = options.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationIdentityUser>(dataProtectionProvider.Create("ASP.NET Identity"));
            }

            return manager;
        }
        catch (Exception ex)
        {
            ex.Process(MethodBase.GetCurrentMethod().DeclaringType, MethodBase.GetCurrentMethod().Name);

            return null;
        }
    }      
}

}


回答1:


I found a working solution for my own problem based on the answer of trailmax.

In stead of the EmailTokenProvider I use the TotpSecurityStampBasedTokenProvider

public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
    // other setup
    this.UserTokenProvider = new TotpSecurityStampBasedTokenProvider<ApplicationUser, string>();
}

For more information about TotpSecurityStampBasedTokenProvider: http://msdn.microsoft.com/en-us/library/dn613297(v=vs.108).aspx




回答2:


Use EmailTokenProvider in UserManager

public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
    // other setup
    this.UserTokenProvider = new EmailTokenProvider<ApplicationUser, string>();
}

I've blogged about it recently.



来源:https://stackoverflow.com/questions/25740139/asp-net-identity-use-generatepasswordresettoken-on-azure-website

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!