Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将当前用户对象保留在内存中_C#_.net_Winforms_Memory_Mvp - Fatal编程技术网

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

C# 将当前用户对象保留在内存中,c#,.net,winforms,memory,mvp,C#,.net,Winforms,Memory,Mvp,在WinForms应用程序中,我希望在应用程序的整个生命周期中将当前登录的用户保留在内存中。因此,在后续的用户操作中,我可以针对该用户检查权限。另一种选择是在本地将用户信息存储在文本文件中,但这似乎不安全 用户登录验证码 private void ValidateUser() { var hashEntered = Encryption.GetHash(_View.UserID, _View.Password); //hash of the salted password entered

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;
        }
    }
}

我建议单身

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;
        }
    }
}

您可以将用户数据存储在类型为
IPrincipal
System.Threading.Thread.CurrentPrincipal
中,该类型还具有名为
Identity
的属性(类型为
IIdentity
)。这两者的区别在于,您只需将用户(假设权限或角色)的安全相关数据存储在主体中,而将其他数据存储在标识中。您可以使用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;
    }
}
这是为了获得用户身份

System.Threading.Thread.CurrentPrincipal.Identity as CustomIdentity

您可以将用户数据存储在类型为
IPrincipal
System.Threading.Thread.CurrentPrincipal
中,该类型还具有名为
Identity
的属性(类型为
IIdentity
)。这两者的区别在于,您只需将用户(假设权限或角色)的安全相关数据存储在主体中,而将其他数据存储在标识中。您可以使用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;
    }
}
这是为了获得用户身份

System.Threading.Thread.CurrentPrincipal.Identity as CustomIdentity

如果我理解正确,您希望保存用户对象,然后检查对此对象的权限。在后端更改用户权限时会发生什么情况?这是“检查时间到使用时间”问题的经典示例。我应该提到的是,权限信息应该保留在内存中。只有用户信息(至少是UserID),如果我理解正确,您希望保存用户对象,然后检查对此对象的权限。在后端更改用户权限时会发生什么情况?这是“检查时间到使用时间”问题的经典示例。我应该提到的是,权限信息应该保留在内存中。如果要使用
lock
,则应
lock
所有对
currentUser
的引用。如果要使用
lock
,则应
lock
所有对
currentUser
的引用。