Search code examples
c#asp.netasp.net-mvcasp.net-identityasp.net-core-mvc

MVC 6 - How to require password to perform controller action?


I am creating an employee scheduling site in ASP.net MVC 6. I have an employee table, shift table and a shiftEmployee table to handle the many to many relationship.

It's configured so that each employee logs into the site using their employee ID number and a password. Then they can see each future shift they are scheduled to. They must acknowledge each assigned shift in a process known as "pulling their pin".

So far everything is working as expected. My goal and my question is this:

When an employee pulls their pin for each shift, I would like them to have to confirm this action by entering their password again, keeping in mind the user is already signed into the site. What is the easiest/correct/most secure way to accomplish this?

The Pull GET/POST methods are basically the same as a standard MVC edit action, simply renamed Pull.

// GET: PullPin/Pull/5
public IActionResult Pull(int? id)
{
    if (id == null)
    {
        return HttpNotFound();
    }

    var shiftEmp = _context.ShiftEmployees.Single(m => m.ShiftEmployeeID == id);

    if (shiftEmployee == null)
    {
        return HttpNotFound();
    }
}

// POST: PullPin/Pull/5
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Pull(ShiftEmployee shiftEmployee)
{
    var user = GetCurrentUserAsync();

    pullPin.PinStatusID = 3; // Status ID #3 = Pulled

    if (ModelState.IsValid)
    {
        _context.Update(shiftEmployee);
        _context.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(shiftEmployee);
}      

And here is my ShiftEmployee class

public class ShiftEmployee 
{

    public int ShiftEmployeeID { get; set; }
    public int ShiftID { get; set; }
    public int EmployeeID { get; set; }
    public int PinStatusID { get; set; }

    public virtual Shift Shift { get; set; }
    [JsonIgnore]
    public virtual Employee Employee { get; set; }
    public virtual PinStatus PinStatus { get; set; }

}

Solution

  • In the standard MVC6 template, it uses ASP.NET Core Identity for the login functionality. Part of that package is the UserManager object (you also get a SignInManager among other things.)

    The UserManager object has a method specifically for checking passwords called CheckPasswordAsync and is used like this:

    _userManager.CheckPasswordAsync(user, password)