Wpf用户安全策略

时间:2013-10-06 06:59:12

标签: .net wpf security mvvm mvvm-light

背景

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

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

我想要什么:

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

我有什么:

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

例如,我的计划是在视图模型(Level1,Level2等)中将元素的可见性绑定到布尔属性(使用boolToVisibility Converter),如果用户级别匹配或更大,该属性将返回true比财产水平。

我的关注:

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

问题:

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

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

2 个答案:

答案 0 :(得分:5)

您可以创建attached property来确定每个控件的访问级别

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(new PropertyMetadata(5))和 转换器绑定到viewModel中的整数UserRole属性,指示用户的访问权限(1 - 5)

希望这有帮助

答案 1 :(得分:1)

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

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”的用户可以看到该按钮。