Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalidate a specific user session

Tags:

c#

asp.net-mvc

When user login I set some information at session:

Session["UserID"] = userUUID;
Session["UserName"] = "John ABC";
Session["UserMail"] = "[email protected]";

When user logout I make Session.Abandon() successfully.

But in case an admin need to remove/block that specific user, I need to kill its session if it exists. I currently can prevent that specific user from login again (via database false record).

How can I browse all started session and then have Session.Abandon() for that specific user?

I've tried this post with no success: Get a list of all active sessions in ASP.NET

Please notice we are working with .Net 4.8.

like image 688
rd1218 Avatar asked Dec 07 '25 08:12

rd1218


1 Answers

NOTE: this answer only exists because I've confused ASP.NET MVC 5 (used by the OP) with MVC 6. It uses the newer techniques and hopefully will be useful for some people.


I think you can put that user's ID into application cache and abandon the current session as soon as the server will start handling that user's next request. (Anyway, the consequences of blocking won't manifest themselves until next request.)

To use cache you have to inject IMemoryCache into a couple of controllers. (The namespace is Microsoft.Extensions.Caching.Memory and you need the NuGet package with same name.) If you're not familiar with dependency injection in ASP.NET MVC, please refer here for an example of injecting IMemoryCache. Although the view is for .NET 7.0 (by the way, why don't you upgrade, it's worth that), the same methods were present in .NET 4.8.

To make IMemoryCache available you have to call builder.Services.AddMemoryCache in Program.cs before builder.Build.

So you have injected it into the controller that handles admin's requests. Now let's store there a list of IDs of blocked users:

// cache is of type IMemoryCache and id is of type int (ID of user to block)
// this is an action method

List<int> blockedIds;  // Or List<long> or even List<ulong>
if (!cache.TryGetValue("BlockedIds", out blockedIds)) {
  blockedIds = new List<int>();
}

blockedIds.Add(id);
cache.Set("BlockedIds", blockedIds);

And add a filter that will retrieve the blocked IDs list from cache and abandon the session if current ID (stored in the session) exists there.

UPDATE: here's an example.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class AbandonBlockedSessionsAttribute : FilterAttribute, IActionFilter {
  public void OnActionExecuting(ActionExecutingContext filterContext) {
    IMemoryCache cache = filterContext.HttpContext.RequestServices.GetService<MemoryCache>();
    
    List<int> blockedIds;
    if (cache.TryGetValue("BlockedIds", out blockedIds)) {
      int? id = filterContext.HttpContext.Session.GetInt32("UserID");
      if (id != null && blockedIds.Contains(id)) {
        filterContext.HttpContext.Session.Abandon();
      }
    }
  }

  public void OnActionExecuted(ActionExecutedContext filterContext) { }
}

And register this filter in Program.cs:

GlobalFilters.Filters.Add(new AbandonBlockedSessionsAttribute());
like image 99
SNBS Avatar answered Dec 08 '25 21:12

SNBS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!