I have an ASP .NET Core web app, and when I created the project the authentication was set up automatically using the individual user accounts option. The database tables for user accounts/roles were also created automatically.
I created my own ApplicationUser class which inherits from IdentityUser, and I added parameters for FirstName, LastName and LockoutReason. (I added these fields to the DB table as well) Now I'm trying to add a feature to allow someone to manually lock out a user, and I can't seem to update the LockoutEnabled field in the database. Every time I do, it automatically gets reset to false.
Here is a picture of the form:
And the GET/POST code for it:
//GET Users lock
public async Task<IActionResult> Lock(string id)
{
if (id == null)
{
return NotFound();
}
var userFromDb = await _db.ApplicationUser.SingleOrDefaultAsync(m => m.Id == id);
if (userFromDb == null)
{
return NotFound();
}
else
{
return View(userFromDb);
}
}
//POST Users lock
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Lock(string Id, ApplicationUser model)
{
var userFromDb = await _db.Users.Where(u => u.Id == Id).FirstOrDefaultAsync();
userFromDb.LockoutEnd = model.LockoutEnd;
userFromDb.LockoutEnabled = true;
userFromDb.AccessFailedCount = model.AccessFailedCount;
userFromDb.LockoutReason = model.LockoutReason;
_db.ApplicationUser.Update(userFromDb);
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string LockoutReason { get; set; }
}
When I click the Lock button, the LockoutEnd and LockoutReason fields are updated correctly, but the LockoutEnabled field remains false and the account isn't locked out.
New POST method after trying to implement solution:
//POST Users lock
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Lock(string Id, ApplicationUser model)
{
var userFromDb = await _db.Users.Where(u => u.Id == Id).FirstOrDefaultAsync();
userFromDb.LockoutEnd = model.LockoutEnd;
userFromDb.AccessFailedCount = model.AccessFailedCount;
userFromDb.LockoutReason = model.LockoutReason;
_db.ApplicationUser.Update(userFromDb);
await _db.SaveChangesAsync();
var user2 = await _userManager.FindByIdAsync(userFromDb.Id);
var result = await _userManager.SetLockoutEnabledAsync(user2, true);
return RedirectToAction(nameof(Index));
}
You need the combination of the two proprieties The LockoutEnabled
and LockoutEnd
.
The LockoutEnabled
is an indicator to see if the user could be locked out or not, and the LockoutEnd
is a DateTimeOffset. So in order to lock the user set the lockout to true and put the value of LockoutEnd
in the future, because A value in the past means the user is not locked out.