ASP.NET Identity WebAPI无效密码重置令牌

Ehs*_*san 5 c# asp.net-mvc asp.net-web-api2 asp.net-identity-2

我有一个Webapi服务,生成密码重置令牌.
令牌生成服务端点:

    [Authorize(Users = "abcd")]
    [HttpGet]
    [ActionName("GenerateForgotPasswordToken")]
    public async Task<IHttpActionResult> GenerateForgotPasswordToken(string key)
    {
        if (key == null || UserManager.FindById(key) == null)
        {
            return InternalServerError(new Exception("User not found"));
        }
        return Ok(await UserManager.GeneratePasswordResetTokenAsync(key));
    }
Run Code Online (Sandbox Code Playgroud)

我的应用程序UserManager:

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        //var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        var manager = new ApplicationUserManager(new UserStore<IdentityUser>(new MTA()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<IdentityUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<IdentityUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
Run Code Online (Sandbox Code Playgroud)

该令牌将用于电子邮件中以向用户发送密码重置URL.该URL指向ASP.NET MVC视图,它是我的WebAPI项目的一部分,显然托管在IIS中的同一Web应用程序中.页面上的密码重置按钮调用我的其他服务端点,重置密码.
Passowrd重置服务终点:

    [HttpGet]
    [AllowAnonymous]
    public async Task<HttpResponseMessage> ResetPassword([FromUri]string email,[FromUri]string code,[FromUri]string password)
    {
        var user = await UserManager.FindByEmailAsync(email);
        var result = await UserManager.ResetPasswordAsync(user.Id, code, password);
        if (result.Succeeded)
        {
            return Request.CreateResponse();
        }
        return Request.CreateResponse(System.Net.HttpStatusCode.Ambiguous);
    }
Run Code Online (Sandbox Code Playgroud)

此外,它可能有助于提到这两个web api端点都在同一个控制器中,在控制器中我定义了一个全局UserManger,如下所示:

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我使用像Advanced REST Client这样的外部工具时,我能够点击第一个端点来生成令牌,然后将令牌连同电子邮件和新密码一起传递到第二个端点,并成功重置密码.但是,当我的ASP.NET MVC控制器使用第一个端点生成的相同令牌并调用passwordReset端点时,令牌无效!我已经确保没有编码/解码问题,并且第二个端点接收的令牌在两个测试中都是相同的.
我的所有WebApi和ASP控制器都在同一个项目中并托管在同一个Web应用程序中.我认为问题可能与基于OwinContext提交请求时有新的令牌提供程序有关,但我不明白为什么它通过Web浏览器调用它.

 public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
Run Code Online (Sandbox Code Playgroud)

Ehs*_*san 1

我在阅读这个问题后发现了问题: Make ASP.NET Identity 2.0 Email inform to WCF and MVC

就我而言,IIS 配置为在运行时生成机器密钥,这就是为什么即使我的所有代码都作为单个应用程序运行,令牌也无效。 应取消选中运行时自动生成

以下是 IIS 机器密钥配置指南:如何使用 IIS 生成机器密钥