2013-10-06 2 views
2

ФОН:Wpf пользователь Стратегия безопасности

Я создаю приложение WPF (.NET 4.5 с MVVM-Light)

я создал роли пользователей в базе данных, примыкающее приложение WPF, где пользователей в WPF приложения имеют назначенную роль (т.е. пользователь, менеджер, владелец, администратор)

ЧТО Я ХОЧУ:

Мой клиент хочет иметь возможность ограничивать то, что пользователи видят и что могут делать пользователи, исходя из их роли. Есть некоторые представления, которые будут видны всем пользователям, поэтому некоторые визуальные элементы (сетки, кнопки и т. Д.) Должны быть скрыты или отключены в зависимости от роли пользователей.

ЧТО Я ИМЕЮ:

Я создал IUserService, который получает впрыскивается в каждый ViewModel. Роли, которые я создал, имеют поле, которое отмечает их уровень безопасности (просто целое число от 1 до 5). Я хочу ограничить видимость визуальных элементов на основе этого числа.

Например, мой план состоит в том, чтобы привязать видимость элемента к логическому свойству (с использованием конвертера boolToVisibility) в viewmodel (Level1, Level2 и т. Д.), И это свойство вернет true, если уровень пользователей совпадает или больше уровня собственности.

МОИ ЗАБОТЫ:

Меня беспокоит то, что это много работы, чтобы реализовать в каждом ViewModel и на каждом визуальный элемент, который необходим. Кроме того, у меня уже есть некоторые визуальные элементы, на которые влияет другая бизнес-логика.

ВОПРОС:

Что является эффективным способом, чтобы ограничить возможность пользователям «просматривать» визуальные элементы, основанные на стратегии роли пользователя?

Я готов начать эту работу, но мне бы хотелось услышать другие идеи сообщества о том, как безопасность на основе роли пользователей реализована в приложении WPF.

+1

Я работаю с «Призмой» и реализовано аналогичное поведение с помощью [навигации по регионам] (http://stackoverflow.com/questions/18984879/asp-net-like-form-based-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 свойства в ViewModel с указанием 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

Это означает, что вам нужно будет указать «Видимость =» {Binding Path = Value, Converter = {StaticResource SecurityLevelToVisibilityConverter}, ConverterParameter = X} "для каждого элемента управления в вашем xaml, который может сильно усложнить его ... –

Смежные вопросы