Какой уровень моего приложения ASP.NET MVC я должен проверять информацию о членстве? - PullRequest
8 голосов
/ 06 октября 2011

У меня есть приложение MVC, которое имеет (упрощенную) структуру, как показано ниже (слева направо)

Пользовательский интерфейс -> КОНТРОЛЛЕРЫ -> УСЛУГИ -> ХРАНИЛИЩЫ -> БАЗА ДАННЫХ

Мы пытались отделить каждый слой от следующего.Мы используем членство .NET для управления безопасностью, и у нас есть функция на основе разрешений, скажем, «Показать все документы для моего типа пользователя» .

Следует:

  1. Уровень услуг не знает о нашем поставщике членства .NET?Тогда у нас были бы методы уровня сервиса, которые выглядели бы как «GetDocumentsByUserType (int UserTypeId) {..}»?

  2. Метод GetDocumentsByUserType () должен знать, что мы используем членство .NET, использовать методы членства, чтобы получить текущий тип пользователя и вернуть соответствующие документы?

Также:

  • Делает ли # 1 мой уровень служб менее безопасным, так как мой уровень контроллера
    может передавать все, что хочет, в качестве UserType?
  • Делает ли # 2 уровень моих услуг слишком зависимым от конкретной технологии, а именно .NET
    Членство?Есть ли другой способ рассмотреть здесь?

Надеюсь, я предоставил достаточно деталей.Пожалуйста, кричите, если нет, и я добавлю.

Спасибо.

1 Ответ

7 голосов
/ 06 октября 2011

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

Сказав это, нет причин не выполнять проверки безопасности на уровне служб, но вы можете сделать этобез необходимости использовать классы членства.Прежде всего, аутентифицированный в данный момент пользователь доступен из Thread.CurrentPrincipal (внутри методов уровня сервиса).Вы можете использовать это IPrincipal для выполнения проверок безопасности.

Во-вторых, вы можете использовать PrincipalPermissionAttribute для применения правил безопасности в методах или классах уровня обслуживания.,Например:

[PrincipalPermission(SecurityAction.Demand, Role="Administrator")]
public void MySecureServiceLayerMethod()
{
    var p = Thread.CurrentPrincipal;
    ....
}

Для работы с ролями вам также необходимо использовать реализацию RoleProvider.

ОБНОВЛЕНИЕ : Как поясняет Уайетт Барнетт в комментарии, использование PrincipalPermission имеет ряд недостатков.Прежде всего, тестирование вашего кода становится более сложным.Еще один (больший) недостаток заключается в том, что вы жестко кодируете имена ролей в своем коде.Эти имена обычно не принадлежат разработчику.

...