Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Password Recovery in ASP.NET MVC5

I am working in an ASP.NET MVC 5 application. Users are able to register and login without any issues. However, when one user forgets his/her password, the forgot password process (already in place) doesn't do anything! No emails are sent to the user with a click here to reset password link.

Currently my ForgotPassword action method looks like this:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
        {
            // Don't reveal that the user does not exist or is not confirmed
            return View("ForgotPasswordConfirmation");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

I am guessing that is left to the developers to implement. I Googled around and found nothing that was straight forward.

What is the easiest way to allow this?

like image 829
J86 Avatar asked Aug 15 '15 14:08

J86


People also ask

How can I recover my asp net password?

Run the "ForgotPassword. aspx" page and enter username or email id and click on submit button.It will send reset password link on your email id. Check your email and click on the reset password link. You will be redirected to the "ResetPassword.

How to reset password in ASP net c#?

In this article I will explain and provide code for implementing Forgot Password functionality in ASP.Net using C# and VB.Net. Using the Forgot Password page, user will be allowed to recover the password using his Email address and then the recovered password will be sent to his registered email address.


Video Answer


1 Answers

Forget password action to generate reset token:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
        {
            // Don't reveal that the user does not exist or is not confirmed
            return View("ForgotPasswordConfirmation");
        }

        // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
        // Send an email with this link
        string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
        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");
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Reset password action to reset password based on generated token:

[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
    return code == null ? View("Error") : View();
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
    var user = await UserManager.FindByNameAsync(model.Email);
    if (user == null)
    {
        // Don't reveal that the user does not exist
        return RedirectToAction("ResetPasswordConfirmation", "Account");
    }
    var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
    if (result.Succeeded)
    {
        return RedirectToAction("ResetPasswordConfirmation", "Account");
    }
    AddErrors(result);
    return View();
}

Relevent view models:

public class ResetPasswordViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
    public string Code { get; set; }
}

public class ForgotPasswordViewModel
{
    public string Email { get; set; }
}

But you need to configure Email service before sending emails.

public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        return configSendGridasync(message);
    }

    private Task configSendGridasync(IdentityMessage message)
    {
        var myMessage = new SendGridMessage();
        myMessage.AddTo(message.Destination);
        myMessage.From = new System.Net.Mail.MailAddress(
                      "[email protected]", "My name");
        myMessage.Subject = message.Subject;
        myMessage.Text = message.Body;
        myMessage.Html = message.Body;

        var credentials = new NetworkCredential("userName","Password");

        // Create a Web transport for sending email.
        var transportWeb = new Web(credentials);

       // Send the email.
       if (transportWeb != null)
       {
           return transportWeb.DeliverAsync(myMessage);
       }
       else
       {
           return Task.FromResult(0);
       }
   }
}

At the end you need to register this class Identity in your user manager configurator add following lines:

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

    // some code here

    manager.EmailService = new EmailService();
}

See Account Confirmation and Password Recovery with ASP.NET Identity (C#) as a step by step tutorial.

like image 144
Sam FarajpourGhamari Avatar answered Sep 28 '22 19:09

Sam FarajpourGhamari