I'm creating an app with Identity 2.0 where Admin can ban other users. When they ban them, they're signed out (when they make their next action/request).
Here's my ban action:
public async Task<ActionResult> Block(ApplicationUser formuser, string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
user.DeleteDate = DateTime.Now;
user.IsConfirmed = false;
await UserManager.UpdateSecurityStampAsync(user.Id);
return RedirectToAction("Index");
}
The UpdateSecuritStampAsync does the log out part. Also I think it's good if I insert Startup.Auth.cs UseCookieAuthentication, because I changed a thing there so that the user is logged out(if I miss adding something important, write in the comments, I'll add it)
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
I changed the default TimeSpan from 30 minutes to 0 (that might be a mistake but it works). The main question of this thread is that I want to create something where it would show a message when the user is logged out, how should I go about doing that? (when admin blocks user, the user, after he reloads his page, gets a message that he was blocked for bad use or something)
Better use Lock/Unlock the user instead of updating the security stamp. Take a look at How to lock and unlock account in Asp.Net Identity provider.
public virtual async Task<IdentityResult> LockUserAccount(string userId, int? forDays)
{
var result = await this.SetLockoutEnabledAsync(userId, true);
if (result.Succeeded)
{
if (forDays.HasValue)
{
result = await SetLockoutEndDateAsync(userId, DateTimeOffset.UtcNow.AddDays(forDays.Value));
}
else
{
result = await SetLockoutEndDateAsync(userId, DateTimeOffset.MaxValue);
}
}
return result;
}
public virtual async Task<IdentityResult> UnlockUserAccount(string userId)
{
var result = await this.SetLockoutEnabledAsync(userId, false);
if (result.Succeeded)
{
await ResetAccessFailedCountAsync(userId);
}
return result;
}
And on your login action or provider you'd use
if (userManager.IsLockedOut(userId))
{
context.SetError("invalid_grant", "The account is locked out of the system.");
return;
}
I'm not sure how to notify the user immediately after being lockedout without him/her attempting to login since you don't have the user's ID or username by the time he/she gets redirected to the login page. But if you do, then you can simply use the IsLockedOut
method to decide whether or not you should display a pop-up saying what it is you want to say to the user.