ResetPasswordAsync返回'无效令牌'何时在WebJob中生成令牌

时间:2016-06-23 20:43:42

标签: c# asp.net asp.net-identity azure-web-sites azure-webjobs

我有一个计划的WebJob ,它每天运行,并检查数据库中所有用户的密码到期日期。如果密码到期日期为今天,它将生成密码重置令牌并通过电子邮件将其发送给用户。然后,用户点击电子邮件中的网址,然后将其带到网站,在网站上输入新密码。

我设法在我的WebJob中生成一个令牌并通过电子邮件发送。但是,当通过我的Asp.NET网站重置密码时,我得到无效令牌。我无法弄清楚为什么。我认为它必须与我的WebJob中的令牌提供程序有关。

1)我的 Asp.NET网站。自定义UserManager:

public class CustomUserManager : UserManager<ApplicationUser> {
    public CustomUserManager(IUserStore<ApplicationUser> store) : base(store) { }          

    public static CustomUserManager Create(IdentityFactoryOptions<CustomUserManager> options, IOwinContext context) {
        var db = context.Get<DataContext>();
        var manager = new CustomUserManager(new UserStore<ApplicationUser>(db));
        // [...]          
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null) {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        // [...]   
        return manager;
    }
}

使用方法如下:

userManager = HttpContext.GetOwinContext().Get<CustomUserManager>();
// [...]
await userManager.ResetPasswordAsync(model.Id, model.Token, model.ConfirmPassword); // token here is invalid (although the string looks like a proper token)

2)我的 WebJob 功能:

public static async void CheckPasswords([QueueTrigger("checkpasswords")] string message) {
    using (var db = new DataContext())
    using (var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db))) {
        var provider = new DpapiDataProtectionProvider("MyApp");
        userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("PasswordReset"));

        var users = await queryHandler.Run(new UserPasswordExpiryQuery());
        foreach (var user in users) {
            var days = new DateCalculations().DaysFromNow(user.PasswordExpiryDate);
            // if password expired today
            if (days == 0) {
                var token = await userManager.GeneratePasswordResetTokenAsync(user.Id);
                var url = string.Format("{0}/resetpass?user={1}&token={2}", settings.BaseUrl, user.Id, HttpUtility.UrlEncode(token));
                // [...] send email logic here
            }
        }
    }
}

稍后编辑

我想我可能已经弄明白了。我在我的Asp.NET应用程序中替换了令牌提供程序:

旧代码:

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

新代码:

 var provider = new DpapiDataProtectionProvider("MyApp");
 manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("ASP.NET Identity"));

稍后会做进一步的测试。

1 个答案:

答案 0 :(得分:0)

您运行的逻辑可能会遇到某些sandbox限制。

如果您直接或indirectly共享您的网络应用程序名称,以及一次此类失败的UTC时间,我可能会确认这一点。