prevent multiple login in asp.net core 2

后端 未结 1 2087
心在旅途
心在旅途 2021-01-28 14:51

Good day,

How do i validate security stamp to prevent multiple login from single user in Asp.Net Core 2 as there\'s no SecurityStampValidationIn

相关标签:
1条回答
  • 2021-01-28 15:32

    I have used Microsoft.Extensions.Caching.Memory.IMemoryCache to implement the same. (Stored the usernames in cache)

    At the time of login (we can do this before validating the password) Step 1: Use Memory Cache as DI to the controller.

    private IMemoryCache SiteCache = null;
    
    public LoginHelper(IMemoryCache Cache)
    { 
      SiteCache = Cache; 
    }
    

    Step 2:

    In your login validation, run this check, if the user already exists in cache.

    private bool VerifyDuplicateLogin(string UserName, bool InsertKey)
    {
        String sKey = UserName.ToLower();
        String sUser = Convert.ToString(SiteCache.Get<string>(sKey));
    
        if (string.IsNullOrEmpty(sUser))
        {
            if (InsertKey)
            {
                string cookieTimeout = appSettingsData.LoginCookieTimeout;
                int timeout = (string.IsNullOrEmpty(cookieTimeout)) ? 3 : int.Parse(cookieTimeout); 
    
                int sessionTimeOut = 5; // HttpContext.Current.Session.Timeout;
    
                sUser = string.Format("{0}^^^{1}", sKey, DateTime.Now.AddMinutes(sessionTimeOut).ToString("yyyy-MM-dd HH:mm:ss"));
    
                // No Cache item, so session is either expired or user is new sign-on,  Set the cache item and Session hit-test for this user
                TimeSpan SlidingTimeOut = new TimeSpan(0, 0, timeout, 0, 0); //(HttpContext.Current.Session.Timeout / 2) 
    
                MemoryCacheEntryOptions cacheOptions = new MemoryCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = SlidingTimeOut
                };
                SiteCache.Set(sKey, sUser, cacheOptions); //OnCachedItemRemoved
    
                session.LoggedInUser = sKey;
            }
    
            //Let them in - redirect to main page, etc. 
            return false;
        }
        else
        {
            // cache item exists, means... "User already in" 
            return true;
        } 
    }
    

    Step 3: Use the following method at the time of log out to remove the username from cache

    public void RemoveLogin(string userName)
    {
        //Clear the cache
        if ((!string.IsNullOrEmpty(userName)) && SiteCache != null)
        {
            String sUser = Convert.ToString(SiteCache.Get<string>(userName));
            if (!string.IsNullOrEmpty(sUser))
            {
                SiteCache.Remove(userName.ToLower());
                session.LoggedInUser = "";
            }
        }
    }
    

    Since I used the Memory cache, whenever the server reset, along with the application, user cache also gets reset and we can get a quick response.

    We can implement the same using Database to store the logged users in a temporarily and with the similar logic, but I felt this approach is little quicker and smother though.

    One drawback with this approach is, if the user closes the browser and wish to log back immediately, he will get a response as user already logged in (means he gets locked until the cache key expires. (We have to be careful while we set expire timeout)

    Thanks

    0 讨论(0)
提交回复
热议问题