将当前用户对象保留在内存中

本文关键字:内存 保留 对象 用户 | 更新日期: 2023-09-27 18:07:50

WinForms应用程序中,我希望在应用程序的整个生命周期中将当前登录的用户保留在内存中。这样在随后的用户操作中,我可以检查针对用户的权限。另一种选择是将用户信息存储在本地的文本文件中,但这似乎并不安全。

用户登录验证码

private void ValidateUser()
{
    var hashEntered = Encryption.GetHash(_View.UserID, _View.Password); //hash of the salted password entered by user.
    var User = _DataService.GetUser(_View.UserID); //user trying to log in
    if (user != null)
    {
        var hashInDB = user.PassWord;
        if (hashEntered != hashInDB)
        {
            MessageBox.Show("Invalid password");
        }
        else
        {
            _MainView.show(); 
        }
    }
    else
    {
        MessageBox.Show("Invalid user name");
    }
}

因此,对于 MainView,当前登录的用户应该可用。

如何在程序退出之前将当前用户对象保留在内存中?

将当前用户对象保留在内存中

我会建议使用单例。

public class UserSession{
    private static volatile User currentUser;
    private static object syncRoot = new Object();
    private UserSession() {}
    public static User GetUser(){
        if (currentUser == null) throw new Exception("Not logged in.");
        return currentUser;
    }
    public static void Login(User user){
        if (currentUser != null) throw new Exception("Already logged in");
        lock(syncRoot){
            currentUser = user;
        }
    }
    public static void Logout(){
        lock(syncRoot){
            currentUser = null;
        }
    }
}
您可以将

用户数据存储在类型为 IPrincipalSystem.Threading.Thread.CurrentPrincipal中,该还具有一个名为 Identity(类型为 IIdentity(的属性。这两者之间的区别在于,您只需将用户(假设权限或角色(的安全关联数据存储在主体中,将其他数据存储在 Identity 中。您可以使用这两个接口的现有实现Microsoft也可以自己构建它们。这是一个例子

class CustomPrincipal : IPrincipal
{
    public IEnumerable<string> Roles { get; set; }
    public IIdentity Identity { get; set; }
    public bool IsInRole(string role)
        {
            // check user for appropriate roles
            return false;
        }
}
class CustomIdentity : IIdentity
{
    public int UserId { get; set; }
    public string AuthenticationType { get; set; }
    public bool IsAuthenticated
    {
        get { return !string.IsNullOrWhiteSpace(Name); }
    }
    public string Name { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        CustomIdentity identity = new CustomIdentity
        {
            UserId = 1,
            Name = "user1"
        };
        CustomPrincipal principal = new CustomPrincipal
        {
            Identity = identity,
            Roles = new List<string> { "admin", "superAdmin" }
        };
        System.Threading.Thread.CurrentPrincipal = principal;
    }
}

主体是ExecutionContext的一部分,因此它将从一个线程复制到另一个线程。 因此,即使您要启动一个新的线程或任务或任何尝试获取Principal的异步作业,它也会在那里

您将使用此代码而不是检索用户主体

System.Threading.Thread.CurrentPrincipal as CustomPrincipal

这是为了获取用户身份

System.Threading.Thread.CurrentPrincipal.Identity as CustomIdentity