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

时间:2020-12-19 03:29:57

I have a Webapi service that generates the password Reset token.
Token generation service end point:

我有一个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));
    }

My application UserManager:

我的应用程序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;
    }

The token will be used in an email to send a password reset URL to the user. That URL points to an ASP.NET MVC view which is part of my WebAPI project and obviously is hosted in the same web application in IIS. The password reset button on the page calls my other service endpoint which resets the password.
Passowrd reset service end point:

该令牌将用于电子邮件中以向用户发送密码重置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);
    }

Also it might help to mention that both those web api endpoints are in the same controller and in the controller I defined a global UserManger as follows:

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

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

When I use an external tool like Advanced REST Client, I am able to hit the first endpoint to generate the token and then pass the token to the second endpoint along with email and new password and successfully reset the password. However when my ASP.NET MVC controller uses the same token generated by the first endpoint and call the passwordReset endpoint , the token is invalid! I already make sure that the is no Encoding/Decoding issue and the token that is received by the second end point is identical in both tests.
Once again all my WebApi and ASP controllers are in the same project and hosted in the same web application. I think the problem might be related to having a new Token provider when a request is comming based on the OwinContext but I don't understand why it works calling it through web browser.

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

 public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)

1 个解决方案

#1


1  

I found the problem after reading this question: Make ASP.NET Identity 2.0 Email confirm token work for WCF and MVC

我在阅读完这个问题后发现了这个问题:为WCF和MVC制作ASP.NET Identity 2.0 Email确认令牌

In my case IIS was configured to generate the Machine Key at runtime and that's why the token was invalid even when all my code was running as a single application. ASP.NET Identity WebAPI无效密码重置令牌

在我的情况下,IIS被配置为在运行时生成机器密钥,这就是令牌无效的原因,即使我的所有代码都作为单个应用程序运行。

Here is a guide to IIS machine key configuration :How to Generate Machine Key using IIS

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

#1


1  

I found the problem after reading this question: Make ASP.NET Identity 2.0 Email confirm token work for WCF and MVC

我在阅读完这个问题后发现了这个问题:为WCF和MVC制作ASP.NET Identity 2.0 Email确认令牌

In my case IIS was configured to generate the Machine Key at runtime and that's why the token was invalid even when all my code was running as a single application. ASP.NET Identity WebAPI无效密码重置令牌

在我的情况下,IIS被配置为在运行时生成机器密钥,这就是令牌无效的原因,即使我的所有代码都作为单个应用程序运行。

Here is a guide to IIS machine key configuration :How to Generate Machine Key using IIS

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