2

背景:

我正在创建一个 WPF 应用程序(带有 MVVM-Light 的 .NET 4.5)

我在支持 WPF 应用程序的数据库中创建了用户角色,其中 WPF 应用程序的用户具有分配的角色(即用户、经理、所有者、管理员

我想要的是:

我的客户希望能够根据用户的角色限制用户看到的内容以及用户可以执行的操作。所有用户都可以看到一些视图,因此应该根据用户角色隐藏或禁用一些视觉元素(网格、按钮等)。

我有的:

我创建了一个注入到每个视图模型中的 IUserService。我创建的角色有一个标记其安全级别的字段(只是一个 1 到 5 的整数)。我希望能够根据这个数字限制视觉元素的可见性。

例如,我的计划是将元素的可见性绑定到视图模型(Level1、Level2 等)中的布尔属性(使用 boolToVisibility 转换器),如果用户级别匹配或大于该属性,该属性将返回 true等级。

我的担忧:

我担心的是,在每个视图模型和所需的每个视觉元素上都需要做大量的工作。此外,我已经有一些受其他业务逻辑影响的视觉元素。

问题:

根据用户角色策略限制用户“查看”视觉元素的能力的有效方法是什么?

我准备开始这项工作,但我很想听听社区关于如何在 WPF 应用程序中实现基于用户角色的安全性的其他想法。

4

2 回答 2

6

您可以创建附加属性来确定每个控件的访问级别

public class VisibilitySecurityLevel 
{
    public static readonly DependencyProperty SecurityLevelProperty = 
        DependencyProperty.RegisterAttached("SecurityLevel", typeof(int), typeof(FrameworkElement), new PropertyMetadata(5));

    public static void SetSecurityLevel(UIElement element, int value)
    {
        element.SetValue(SecurityLevelProperty, value);
    }
    public static int GetSecurityLevel(UIElement element)
    {
        return (int)element.GetValue(SecurityLevelProperty);
    }
}

将其应用于您希望由用户角色管理的控件

    <Button local:VisibilitySecurityLevel.SecurityLevel="3"/>
    <CheckBox local:VisibilitySecurityLevel.SecurityLevel="2"/>

使用基本隐式样式,该样式将使用转换器根据其安全级别绑定控件的可见性

       <local:AccessLevelToVisibilityConverter x:Key="AccessLevelToVisibilityConverter"/>
       <Style TargetType="{x:Type FrameworkElement}">
            <Setter Property="Visibility">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource AccessLevelToVisibilityConverter}">
                        <Binding Path="UserRole"/>
                        <Binding RelativeSource="{RelativeSource Mode=Self}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>

转换器:

public class AccessLevelToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        int userRole = (int)values[0];
        int controlAccessLevel = (int)(values[1] as FrameworkElement).GetValue(VisibilitySecurityLevel.SecurityLevelProperty);

        return (userRole <= controlAccessLevel) ? Visibility.Visible : Visibility.Hidden;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

请注意,在我的实现中,最低用户角色 5 是最受限制的角色(只能看到访问级别为 5 的控件),而用户角色 1 是最高权限的(可以看到访问级别为 1 -5 的控件)。这就是为什么默认访问级别是 5 ( ) 并且转换器绑定到viewModel 中new PropertyMetadata(5)的整数属性,指示用户的访问权限 (1 - 5)UserRole

希望这可以帮助

于 2013-10-06T09:40:41.103 回答
2

根据我的评论,这里是转换器:

class SecurityLevelToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(int.Parse((string)value) < int.Parse((string)parameter)) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

下面是如何在 XAML 中使用它的示例:

<Button Style="{StaticResource MyButtonStyle}" 
        DataContext="{DynamicResource System.CurLevel}" 
        Visibility="{Binding Path=Value, Converter={StaticResource SecurityLevelToVisibilityConverter}, ConverterParameter=3}"/>

“ConverterParameter=3”表示安全级别为“3”的用户可以看到按钮。

于 2013-10-06T07:59:25.650 回答