WPF UI权限,在数据库中定义

时间:2015-10-02 12:54:52

标签: c# wpf permissions user-permissions

到目前为止,我已经使用非常简单的用户角色版本和每个Visibility / IsEnabled / Command.CanExecute和转换器控制权限:

 <TabItem Visibility="{Binding UserRole, Converter={StaticResource PackerVisible}}" >...

我的转换器看起来像:

 <conv:UserVisibilityConverter x:Key="PackerVisible" Allow="Packer,Lagerleiter,Entwickler" />

如果您没有多少角色,这相对容易,但即使如此,您也没有很好的概述:谁可以访问此元素或其他UI元素。

另一个坏处是UserRoles(存储在DB中)在这里用作字符串 - Allow="Role1, Role2, Role3"

在我的新项目中,我有更多的角色/权限,这使得这个解决方案变得更加丑陋。

我已经搜索过,没有发现如何更好地实现它。更好的是,可以在代码中使用枚举作为角色名称,但如何将枚举与数据库同步?

我发现的其他解决方案(solution1solution2)更好,因为他们不需要转换器,但权限在XAML中再次设置为字符串:

// AuthToVisibility
<Image ... Visibility="{op:AuthToVisibility "CanView"}" />

// AutoToEnabled
<MenuItem IsEnabled="{op:AuthToEnabled "CanClose"}">...</MenuItem>

在UI中处理存储在数据库中的权限的最佳方法是什么?有什么模式吗?

1 个答案:

答案 0 :(得分:2)

只要没有人回答,我会尝试。我有一个更好(不理想)的解决方案 首先实现,下面我将写一些关于它的文字。

  1. 权限类:

    public class Permission
    {
        public bool IsAllowed { get; set; }
        internal List<string> AccessControllList { get; private set; }
    
        internal Permission(params string[] allowedRoles)
        {
            IsAllowed = false;
            AccessControllList = new List<string>();
            foreach (var role in allowedRoles)
            {
                AccessControllList.Add(role);
            }
        }
    }
    
    • 主要属性 - IsAllowed
    • 允许运行/查看某个功能/块
    • 的角色名称AccessControlList的内部列表
    • 内部构造函数来填充ACL 小而简单。
  2. PermissionController:

    public class PermissionController : INotifyPropertyChanged
    {
        #region Singleton
        ...
        //constructor
        private PermissionController()
        {
            Initialize();
            UserModel.Instance.LoginChanged += new LoginChangedEventHandler(UpdatePermissions);
        }
        #endregion
    
        //role names from database as string const
        private const string PACKER = "Packer";
        private const string CHIEF = "Lagerleiter";
        private const string QSWORKER = "QSMitarbeiter";
        private const string DEVELOPER = "Entwickler";
    
        PropertyInfo[] _localProperties;
    
        //Permissions defined as properties
        public Permission WEstart { get; private set; }
        public Permission WEreset { get; private set; }
        public Permission WEclose { get; private set; }
    
        public Permission Manage { get; private set; }
        public Permission TestPhase { get; private set; }
    
        private void Initialize()
        {
            _localProperties = typeof(PermissionController).GetProperties();
    
            WEwork          = new Permission(PACKER, CHIEF);
            WEreset         = new Permission(CHIEF);
            WEclose         = new Permission(PACKER, CHIEF);           
            Manage          = new Permission(CHIEF);
            TestPhase       = new Permission(DEVELOPER);
        }
    
        private void UpdatePermissions(object sender, EventArgs e)
        {            
            var currentUser = (UserModel)sender;
    
            //if user is logged out -> return
            if (!currentUser.IsLoggedIn)
                return;
    
            var permissionType = typeof(Permission);
            foreach (PropertyInfo property in _localProperties)
            {
                if (property.PropertyType != permissionType)
                    continue;
    
                var permission = (Permission)property.GetValue(this, null);
                permission.IsAllowed = false;
                if (permission.AccessControllList.Contains(currentUser.UserRole))
                {
                    permission.IsAllowed = true;
                }
                OnPropertyChanged(property.Name);
            }
        }
    
        #region INotifyPropertyChangedImplementation
        ...
        protected virtual void OnPropertyChanged(string propertyName)
        {
            ...
        }
        ...
        #endregion 
    }
    
    • 实现INotifyPropertyChanged(直接在XAML中使用其属性)
    • 使用Singleton-Pattern只有一个实例
    • 具有const个字符串,用于在数据库中定义的用户角色。它只是代码中的一个位置,其中用户角色用作字符串值。如果需要更新角色列表 - 您应该只更改const列表和初始化方法(权限初始化)。
    • 订阅User.LoginChanged事件并更新每个权限的IsAllowed属性。
  3. 将Permission对象(在XAML中设置)转换为Visibility / IsEnabled属性的不同转换器(IValueConverter)(如果需要,可以发布代码)

  4. XAML:

    <Image Visibility="{Binding Permissions.TestPhase, Converter={StaticResource PermissionToVisibility}}" ... />
    <TextBox IsEnabled="{Binding Permissions.WEwork, Converter={StaticResource PermissionToBoolean}}" ... />
    <Button Command="..." CommandParameter="{Binding Permissions.Manage}" ... />
    
    • 如果您重新定义角色权限,则无需编辑XAML
    • 您可以处理Visibility / IsEnabled / Command.CanExecute
  5. 现在我可以自由管理GUI中的用户角色,角色权限仅在代码中定义。但是我不需要管理角色权限 足够好的是,如果我需要更新/更改角色权限,我将只在代码中的一个位置执行此操作。

    如果您有任何问题或建议 - 我愿意接受对话。