2013-10-06 64 views
2

背景:WPF用戶安全戰略

我創建一個WPF應用程序(.NET 4.5,MVVM光強)

我已經在備份WPF應用程序在用戶數據庫中創建用戶角色在WPF應用程序中有一個分配的角色(即用戶,經理,老闆,管理

我想:

我的客戶希望能夠根據用戶的角色限制用戶看到的內容以及用戶可以執行的操作。所有用戶都會看到一些視圖,因此根據用戶的角色,應該隱藏或禁用一些視覺元素(網格,按鈕等)。

我有:

我已經創建了一個被注入到每一個視圖模型的IUserService。我創建的角色有一個標記其安全級別的字段(簡單地說是1到5的整數)。我希望能夠根據這個數字來限制視覺元素的可見性。

例如,我的計劃是將元素的可見性綁定到視圖模型(Level1,Level2等)中的布爾屬性(使用boolToVisibility Converter),並且如果用戶級別匹配或者是該屬性將返回true大於財產水平。

我的顧慮:

我擔心的是,這是一個大量的工作在每一個視圖模型,同時還需要每一個視覺元素來實現。另外,我已經有了一些受其他業務邏輯影響的視覺元素。

問題:

什麼是限制用戶的能力基於用戶角色的策略,以「視圖」視覺元素的有效途徑?

我準備開始這項工作,但我很想聽到來自社區的一些其他想法,瞭解如何在WPF應用程序中實現基於用戶角色的安全性。

+1

我的工作與'Prism'並通過[區域導航]實現了類似的行爲(http://stackoverflow.com/questions/18984879/asp-net-like-form-b​​ased-authentication-in-wpf-mvvm-prism/18985193#18985193 )。我對每個角色都有幾個視圖,在'ConfirmNavigationRequest'中決定誰可以訪問哪個視圖。也許在MVVM-Light中有類似的界面... –

+0

我會使用轉換器根據當前角色返回所需的可見性狀態,將要管理的控件的可見性綁定到代表當前用戶角色的屬性。您也可以使用轉換器參數傳遞允許的角色。 – Taras

+1

作爲警告,如果您使用Snoop之類的工具,則可以在運行時更改控件的可見性,因此它對確保安全性在較低級別強制執行也很重要。 – gouldos

回答

3

您可以創建一個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))和 該轉換器綁定到視圖模型的整數UserRole屬性,來指示用戶的訪問priviliages(1 - 5)

希望這有助於

+1

有點之後,但我最終使用了這種方法。感謝Omribitan –

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」的安全級別可以看到按鈕。

+0

這將意味着你必須爲你的xaml中的每個控件指定'Visibility =「{Binding Path = Value,Converter = {StaticResource SecurityLevelToVisibilityConverter},ConverterParameter = X}'',這可以大大地複雜它... –