C# 使用枚举标志位的WPF基于权限的授权

C# 使用枚举标志位的WPF基于权限的授权,c#,wpf,permissions,enums,C#,Wpf,Permissions,Enums,我已经做了一个月的C#,所以请原谅这个问题的“地方性”,但我已经研究了几个小时,我遇到了麻烦 我已经看到了使用IIdentity和IPrincipal的WPF应用程序的基于角色的授权的左右示例 我找不到很多信息,但是,在一种更基于权限的授权方法中,在这个应用程序中,想象没有组,只有一个权限和用户列表,您可以为任何人分配任何权限 我希望能够: 1) 能够基于用户权限控制UI/元素,状态为:启用、只读、不可见、折叠(如图所示) 2) 能够在类或方法级别指定需要哪些权限(类似于) 而不是: [Prin

我已经做了一个月的C#,所以请原谅这个问题的“地方性”,但我已经研究了几个小时,我遇到了麻烦

我已经看到了使用
IIdentity
IPrincipal
的WPF应用程序的基于角色的授权的左右示例

我找不到很多信息,但是,在一种更基于权限的授权方法中,在这个应用程序中,想象没有组,只有一个权限和用户列表,您可以为任何人分配任何权限

我希望能够:

1) 能够基于用户权限控制UI/元素,状态为:启用、只读、不可见、折叠(如图所示)
2) 能够在类或方法级别指定需要哪些权限(类似于)

而不是:

[PrincipalPermission(SecurityAction.Demand,Role=“Administrators”)]

我想要像这样的东西:

[PrincipalPermission(SecurityAction.Demand,Permission=“可以添加用户”)]

现在我看到的唯一方法是利用
ICommand
并将授权逻辑放入
CanExecute
方法中,使用大量字符串比较来查看用户是否具有执行请求的操作所需的权限,例如:

// Employee class
public bool HasRight(SecurityRight right)
{
    return employee.Permissions.Contains(right);
}

// Implementation, check if employee has right to continue
if (employee.HasRight(db.SecurityRights.Single(sr => sr.Description == "Can edit users")))
{
    // Allowed to perform action
}
else
{
    // User does not have right to continue
    throw SecurityException;
}
有人告诉我枚举标志可能就是我要找的

我想我理解enum/flag/bits,但不足以完成实现

如果我有:

员工模型
EmployeeViewModel
ThingTwoModel
ThingTwoViewModel
主视图

我不知道所有的东西都去了哪里,以及如何把它们联系在一起。。。。以下是我到目前为止的情况(我意识到这不是一个有效的例子……这是我的问题!):

[标志]
公共枚举权限
{
无=0,

Create=1那么,
testFlag
就不能正常工作了。我想你需要的是(c#program snippet):

void Main()
{
//可以创建用户,但不能读回信息
var userCanBeCreatedPermission=Permissions.Create | Permissions.User;
//可以创建和回读
var usercanbecreatedReadbackPermission=userCanBeCreatedPermission | Permissions.Read;
userCanBeCreatedPermission.HasFlag(Permissions.User.Dump();//返回true
(userCanBeCreatedPermission.HasFlag(Permissions.User)和&userCanBeCreatedPermission.HasFlag(Permissions.Read)).Dump();//返回false
//检查标志的另一种方法是组合标志并执行and掩码检查
//以上内容可以写成
((userCanBeCreatedPermission&(Permissions.User | Permissions.Read))==(Permissions.User | Permissions.Read)).Dump();//返回false
//使用变量具有可读性的组合权限&使用和掩码:
var desiredPermissions=Permissions.User | Permissions.Read;
//正在与同时具有创建和读取权限的用户进行检查
((UserCanBeCreatedReadbackPermission&desiredPermissions)=desiredPermissions.Dump();//返回true,因为此用户可以读回用户信息
((usercanbecreatedReadbackPermission&Permissions.Delete)=Permissions.Delete).Dump();//返回false,因为无法删除该用户
}
[旗帜]
公共枚举权限
{
无=0,
创建=1最终解决方案(.linq):

void Main()
{
//权限定义
var userCreate=新授权(Permissions.Create);
var userRead=新授权(Permissions.Read);
var Create=新授权(Permissions.Create);
var carroread=新授权(Permissions.Read);
//使用者
var user=新用户();
//用户还没有权限
if(user.IsAuthorized(Permissions.Create))
“我可以创建用户“.Dump();
其他的
“不为我创建用户”。Dump();
//现在用户可以创建用户
user.Authorizations.Add(userCreate);
if(user.IsAuthorized(Permissions.Create))
“我可以创建用户“.Dump();
其他的
“不为我创建用户”。Dump();
//用户可以阅读胡萝卜
user.Authorizations.Add(读取);
if(user.IsAuthorized(Permissions.Create))
“我可以创造胡萝卜”;
其他的
“不要为我创造胡萝卜”。Dump();
if(user.IsAuthorized(Permissions.Read))
“我能读胡萝卜”;
其他的
“不要为我读胡萝卜”;
//用户现在可以创建胡萝卜了
user.Authorizations.Add(创建);
if(user.IsAuthorized(Permissions.Create))
“我可以创造胡萝卜”;
其他的
“不要为我创造胡萝卜”。Dump();
}
[旗帜]
公共枚举权限:ulong
{

Create=1您可以利用LINQ进行以下授权:
返回Authorizations.OfType().Any(x=>(x.Permissions&permission)=权限)
还请记住,在检查位掩码时,您可能不想使用直接的
=
,而是要使用
&
+
=
我还注意到您正在为同一类型添加多个权限。您可能希望查看权限是否已经存在,只需更新现有的权限掩码。这将导致当你处理持久性的问题时,它会派上用场。
    [Flags]
    public enum Permissions
    {
        None = 0,
        Create = 1 << 0,
        Read = 1 << 1,
        Update = 1 << 2,
        Delete = 1 << 3,

        User = 1 << 4,
        Group = 1 << 5
    }

    public static void testFlag()
    {
        Permissions p;
        var x = p.HasFlag(Permissions.Update) && p.HasFlag(Permissions.User);
        var desiredPermissions = Permissions.User | Permissions.Read | Permissions.Create;
        if (x & p == desiredPermissions)
        {
            //the user can be created and read by this operator
        }
    }
void Main()
{
    //can create user but not read the information back
    var userCanBeCreatedPermission = Permissions.Create | Permissions.User;

    //can create and readback
    var userCanBeCreatedAndReadBackPermission = userCanBeCreatedPermission | Permissions.Read;

    userCanBeCreatedPermission.HasFlag(Permissions.User).Dump(); //returns true

    (userCanBeCreatedPermission.HasFlag(Permissions.User) && userCanBeCreatedPermission.HasFlag(Permissions.Read)).Dump(); //returns false

    //alternative way of checking flags is to combine the flags and do an And mask check
    //the above can be written as
    ((userCanBeCreatedPermission & (Permissions.User | Permissions.Read)) == (Permissions.User | Permissions.Read)).Dump(); //returns false

    //using a variable to have combined permissions for readibility & using And mask:
    var desiredPermissions = Permissions.User | Permissions.Read;

    //checking with user that has both Create & Read permissions

    ((userCanBeCreatedAndReadBackPermission & desiredPermissions) == desiredPermissions).Dump(); // returns true because the user information can be read back by this user

    ((userCanBeCreatedAndReadBackPermission & Permissions.Delete) == Permissions.Delete).Dump(); // returns false because the user can't be deleted
}

[Flags]
public enum Permissions
{
   None = 0,
   Create = 1 << 0,
   Read = 1 << 1,
   Update = 1 << 2,
   Delete = 1 << 3,

   User = 1 << 4,
   Group = 1 << 5
}
void Main()
{
    // Permissions definition
    var userCreate = new Authorization<User>(Permissions.Create);
    var userRead = new Authorization<User>(Permissions.Read);

    var carrotCreate = new Authorization<Carrot>(Permissions.Create);
    var carrotRead = new Authorization<Carrot>(Permissions.Read);

    // User
    var user = new User();

    // User has no permissions yet
    if(user.IsAuthorized<User>(Permissions.Create))
        "I can create User".Dump();
    else
        "No creating User for me".Dump();

    // Now user can Create users
    user.Authorizations.Add(userCreate);            
    if(user.IsAuthorized<User>(Permissions.Create))
        "I can create User".Dump();
    else
        "No creating User for me".Dump();

    // User can read carrots
    user.Authorizations.Add(carrotRead);

    if(user.IsAuthorized<Carrot>(Permissions.Create))
        "I can create carrots".Dump();
    else
        "No creating carrots for me".Dump();

    if(user.IsAuthorized<Carrot>(Permissions.Read))
        "I can read carrots".Dump();
    else
        "No reading carrots for me".Dump();

    // User can now create carrots
    user.Authorizations.Add(carrotCreate);
    if(user.IsAuthorized<Carrot>(Permissions.Create))
        "I can create carrots".Dump();
    else
        "No creating carrots for me".Dump();            

}

[Flags]
public enum Permissions : ulong
{
    Create = 1 << 0,
    Read = 1 << 1,
    Update = 1 << 2,
    Delete = 1 << 3
}

public abstract class Auth{

}
public class Authorization<T> : Auth {
    public Authorization(Permissions permissions){ this.Permissions = permissions; }
    public Permissions Permissions {get;set;}
}

public class Carrot{
    public int Id{get; set;}
}

public class User{
    public User(){ Authorizations = new List<Auth>(); }
    public List<Auth> Authorizations{get; set;}
    public bool IsAuthorized<T>(Permissions permission){
        foreach(var auth in Authorizations)
            if(auth is Authorization<T>){
                var a = auth as Authorization<T>;
                if(a.Permissions == permission)
                    return true;
            }

        return false;
    }
}