Уровень безопасности данных в MVC 3 - PullRequest
2 голосов
/ 11 октября 2011

Мне любопытно, как лучше подходить к обеспечению безопасности на уровне данных в MVC 3. Позвольте мне нарисовать картинку.

Существует просмотр событий. В этом событии указано название события и список игроков, которые играют в этом событии.

В зависимости от отношения текущего пользователя к этому событию каждый пользователь получит существенно различное представление.

Например, если пользователь является Организатором, он может просматривать и управлять доступностью всех других пользователей для этого события.

Если пользователь просто участвует в этом событии, то очевидно, что пользователь может манипулировать только своей собственной доступностью.

Есть больше комбинаций, чем это.

Я знаю о фильтрах пользовательских действий, но это кажется излишним.

Вместо этого я выбрал подход, при котором в Индексе события есть оператор switch, который будет перенаправлять в соответствующий View, например, OrganiserEventView или PlayerEventView.

Это легко. Я думаю.

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

Я на правильном пути или есть лучший способ?

Ответы [ 4 ]

3 голосов
/ 24 ноября 2011

Дункан,

Это то, с чем я сталкиваюсь в каждом приложении.Вот некоторый контекст: я работаю на одном факультете в крупном университете, поэтому нам приходится иметь дело с несколькими источниками данных.Большинство наших приложений имеют защиту, которая объединяет университетские «центральные ИТ» службы безопасности, такие как централизованная аутентификация и активный каталог, а также «доморощенные» роли и разрешения.

Наши приложения должны представлять разные представления и действия для разных пользователей на основе данных как в «доморощенных» приложениях (используемых внутри нашего отдела), так и данных предприятия.

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

  1. Статические и Динамические роли.Статические роли не зависят от данных (например, я получаю роль разработчика в приложениях), в то время как динамические роли зависят от SecurityContext (например, финансовый сотрудник департамента получает роль «Финансовый сотрудник», когда она просматривает счета своего отдела).
  2. Разрешения, которые назначены статической или динамической ролям.
  3. SecurityContext, который инкапсулирует все данные, необходимые для проверки разрешения, которые должны быть выполнены, включая текущего пользователя и любые данные (например, номера счетов, идентификаторы документов предложений, даты транзакций, что угодно).
  4. SecurityContextValidator, который принимает SecurityContext и возвращает набор или роли, которые действительны для указанного пользователя в указанном SecurityContext.Таким образом, логика, которая определяет, кто может видеть, что находится в этом классе.
  5. Один SecurityContextValidator на SecurityContext.Это сопоставление регистрируется при инициализации с помощью SecurityContextManager.Я использую Ninject для загрузки моего модуля безопасности, который выполняет это при запуске.
  6. Контекст по умолчанию, используемый, если в разрешении не указан SecurityContext, который просто содержит основную информацию из безопасности Asp.Net.
  7. SecurityService, предоставивший пользователю, SecurityContext и разрешение, определяет все роли, которые пользователь имеет в этом SecurityContext, и проверяет, есть ли у какой-либо из ролей проверяемое разрешение.

При этомточка, вот пример потока в Asp.Net MVC:

  • Получить HttpRequest
  • Аутентификация с помощью проверки подлинности с помощью форм
  • Путь к действию контроллера
  • , если(Permission.GetByName ("CanDoSomething"). IsAllowed ()) {// продолжить

- [Inside Permission.IsAllowed] -

  • SecurityService получает SecurityContext
  • Найти SecurityContextValidator для указанного SecurityContext
  • Объединить все статические и динамические роли из SecurityContextValidatили
  • Перебирайте роли и проверяйте, есть ли у каждой из них запрашиваемое разрешение.
  • Верните True или False!

Чтобы упростить задачу, я выбрал однусделайте следующий шаг и создайте AbstractContextProtectedAttribute, который ожидает делегата SecurityContextFactory, который может создать SecurityContext (например, с помощью HTTPRequest) и разрешение для проверки с указанным SecurityContext.Подклассы этого класса могут затем использоваться для украшения действий контроллера.

Фу!Итак, теперь все, что мне нужно, настроить таблицу пользователей, ролей, разрешений и сопоставить их друг с другом, определить все разрешения в базе данных.Я написал подключаемый SecurityPersistenceService, который делает инфраструктуру безопасности независимой от используемой стратегии персистентности - к сожалению, у нас есть все - от DataReaders, DataAdapters до Linq2Sql и EF.Но, по крайней мере, мы можем написать код, подобный этому:

[Protected("CanAccessX")] // Checks using default context
public class SomeController 
{
    [Protected("CanSeeY")] // Checks using default context
    public PartialViewResult GetY(<parameters>) 
    {
        var canSeeY_Variation1 = Permission.Get("CanSeeY_Variation1") ;
        var y_Variation1_Context = new Y_Variation1_Context { <build your context here> } ;
        if (canSeeY_Variation1.IsAllowed(y_variation1_Context))
        {
            <return variation 1 view>
        }

        // Y_Variation_2...etc
    }
}

И чтобы это работало, при запуске я регистрирую соответствующие валидаторы:

public class MyNinjectModule
{
    public override void Load()
    {
        // Wire up a persistence service for the security framework
        // to use.
        SecurityService.SecurityPersistenceService = new MySecurityPersistenceServiceImplementation() ;

        // This is what allows the SecurityService to figure out what Validator to use
        // in a specified Context to get the User's Roles.          
        SecurityService.RegisterValidator<Y_Variation1_Context>(new Y_Variation1_ContextValidator(...)) ;
    }
}

Сейчас я работаю над дополнением к этой инфраструктуре, которое позволяет мне выполнять эти проверки над перечисляемыми данными, таким образом, добавляя все объекты моего домена в инфраструктуру безопасности. Единственный чистый способ сделать это - использовать АОП. Я работал на Java и использовал AspectJ. Сейчас я рассматриваю PostSharp.

Надеюсь, это даст вам возможность подумать о вашей проблеме.

1 голос
/ 11 октября 2011

Ответ будет меняться в зависимости от размера, сложности и прогнозируемого роста вашего приложения. Хотя безопасность в контроллере, а затем и другие представления работают, есть компромиссы. Например, репликация кода / разметки может быть откатом назад. Для сложных приложений портлеты могут помочь, но это тяжелые вещи. Представление может изменяться в зависимости от ролей безопасности и доступа, вы будете передавать параметр / данные из контроллера, как и все остальное, если они еще не доступны через сеанс. Я бы создал вспомогательный метод для представлений, чтобы использовать его, чтобы логика / правила не заканчивались в представлении.

1 голос
/ 11 октября 2011

Как я вижу ваш вопрос, безопасность на основе ролей - это путь.

Если они организатор, то они роль организатора. Однако вам нужно немного абстрагироваться. Поскольку роль организатора в теории тогда была бы организатором для всех других событий, вам нужен метод, который делает это определение и заполняет роли по запросу, поэтому пользователь А является организатором события А, но не организатором события B. В идеале это необходимо произойдет до доступа к коду контроллера, поэтому вы можете выбрать global.asax.cs или фильтр авторизации.

0 голосов
/ 11 октября 2011

Использование ролей и пользовательских атрибутов ролей кажутся подходящими (хотя я могу сказать, что без кода или лучшего понимания вашей кодовой базы никто не сможет дать вам «лучший» способ решения вашей проблемы) ,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...