2

Using the provided template for an Asp.Net OWIN MVC app. I get an AccountController with a ForgotPassword method that calls...

var code = await manager.GeneratePasswordResetTokenAsync(user.Id);

After some research I find out that the code is protected by OWIN security, using the DpapiDataProtectionProvider Protect method. Which is fine.

What's throwing me off here is the code that is being returned is super long, and I'm not sure if I'm doing it wrong or if there is something that I can change to shorten it. One important thing to note is that I am setting the IDataProtector by hand with the following code...

//ctor
public MyUserManager(IUserStore<MyUser, int> store) : base(store)
{
    var provider = new DpapiDataProtectionProvider("MvcApplication");
    UserTokenProvider = new DataProtectorTokenProvider<MyUser, int>(provider.Create("EmailConfirmation")); 
}

Any help would be greatly appreciated!

matt_dev
  • 5,176
  • 5
  • 33
  • 44
  • What do you mean by "super long"? Please provide an example code and explain why don't you like its length? – Codeguard Jun 07 '15 at 15:07

1 Answers1

0

You can't shorten DpapiDataProtectionProvider output but you can for example generate a GUID (or some other random string), substitute it in callbackUrl and save it in your DB along side with DpapiDataProtectionProvider code. Then, in a ResetPassword method, retreive original protected code from database with a provided GUID and call ResetPasswordAsync.

It could look something like this(pseudo code):

public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    string originalCode = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
    string code = Guid.NewGuid().ToString(); // or other short code

    /*
    Save to database code and originalCode
    */

    var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
    await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
    return RedirectToAction("ForgotPasswordConfirmation", "Account");
}

And your ResetPassword

public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
    /*
    retreive originalCode from database by using model.Code
    */
    var originalCode = from_db;
    var result = await UserManager.ResetPasswordAsync(user.Id, originalCode, model.Password);

    AddErrors(result);
    return View();
}

Another way is to implement IDataProtector and use some other algorithm to protect and unprotect data that will be shorter in length.

Marko M.
  • 789
  • 3
  • 9