.Net Членство в приложении nTier

Допустим, у меня есть приложение ASP.Net MVC, и это приложение (UI) ссылается на уровень бизнес-логики (BLL), а BLL ссылается на мой уровень доступа к данным (DAL).

Я использую поставщика настраиваемого членства и ролей для авторизации.

Я пытаюсь определить, какие слои должны ссылаться на моего поставщика членства.

В MVC вы можете выполнять проверки авторизации следующим образом:

[Authorize(Roles = "SomeRoleName")]
public ActionResult Index()
{
//do something
}

И в моем BLL я могу проверить, находится ли пользователь в роли:

public static bool IsRoleEditor(User user, Role userRole)
  {
   bool retValue = false;

   if (user.Application.AppID == UserRole.Application.AppID)
   {
        if (Roles.IsUserInRole("ModifyRoles"))
        {
           retValue = true;
        }


    return retValue;
   }

Если я это сделаю, мне придется ссылаться на классы членства и создавать их экземпляры на обоих уровнях. Это правильный способ создать подобное приложение? Похоже, слишком много избыточности.

Поскольку у меня есть BLL, могу ли я избегать использования атрибутов «[Authorize (Roles =" SomeRoleName ")]" и вместо этого вызывать функцию BLL из кода MVC, чтобы проверить, находится ли пользователь в роли? Если я сделаю это, MVC все равно понадобится ссылка на поставщика членства для аутентификации и так далее, чтобы воспользоваться преимуществами входа и других элементов управления ASP, верно?

Я ухожу с базы и еду в неправильном направлении?


person Jay    schedule 10.09.2009    source источник


Ответы (8)


На мой взгляд, это слабость конструкции членство / роль.

Способ, которым я мог бы обойти это, например, чтобы иметь авторизацию на основе ролей на уровнях UI и BLL в распределенном n-уровневом приложении, заключался бы в предоставлении службы на уровне BLL, которая предоставляет соответствующие биты (GetRolesForUser и т. Д.) И реализуется путем вызова RoleProvider на сервере.

Затем реализуйте настраиваемый RoleProvider на клиенте, который реализуется путем вызова службы, предоставляемой BLL.

Таким образом, уровень пользовательского интерфейса и уровень BLL используют один и тот же RoleProvider. Уровень пользовательского интерфейса может использовать сведения о ролях текущего пользователя для улучшения пользовательского интерфейса (например, скрытие / отключение элементов управления пользовательского интерфейса, соответствующих неавторизованным функциям), а BLL может гарантировать, что пользователи не могут выполнять бизнес-логику, для которой они не авторизованы.

person Joe    schedule 25.09.2009

Отличный вопрос, я задала себе то же самое сегодня. Одна из моих идей (но я не совсем уверен, что это лучший способ) - использовать интерфейс (например, IRoleProvider), который вы можете передать своему BLL, чтобы проверить свой доступ.

public static bool IsRoleEditor(User user, IRoleProvider rp)
{
     return (rp.IsUserInRole(user,"ModifyRoles"));
}

При этом вы по-прежнему проверяете свой доступ в своем BLL, вы можете использовать макет в своих модульных тестах для проверки своей логики, и вам просто нужно создать класс (или реализовать его в классе baseController) на своем веб-сайте MVC, который будет реализовывать IRoleProvider и выполните соответствующую проверку с помощью API авторизации ASP.NET.

Надеюсь, это поможет.

person mberube.Net    schedule 15.09.2009

Получите свой объект User для реализации интерфейса IPrincipal и разбросайте его по слоям. Тогда вы все еще можете использовать встроенный атрибут [Autorize].

Хотя эта статья была написана более трех лет назад, может помочь. Он начинает проникать в суть IPrincipal на полпути.

HTHS
Чарльз

person Charlino    schedule 11.09.2009
comment
Обязательно используйте атрибут Authorize в MVC. Вам не нужно вручную проверять IsInRoles. - person Anthony Gatlin; 14.09.2009
comment
Проблема в том, что мне действительно нужно обрабатывать дополнительную бизнес-логику в дополнение к IsInRole или Authorize, которые, как я думал, всегда должны быть в BLL. Я мог бы передавать объект пользователя везде, но тогда почему бы просто не пропустить Authorize и использовать только BLL. - person Jay; 14.09.2009

Почему бы не передать роли в ваш BLL, чтобы у вас не было никакой зависимости от членства. Или используйте интерфейс, подобный предложенному MartinB.

Что произойдет в будущем, когда ваши заинтересованные стороны решат использовать другую форму аутентификации, а вы больше не будете работать с объектом Role?

Пример:

IsRoleEditor(User user, string[] roles)
{
  return roles.Contains("ModifyRoles");
}
person Denny Ferrassoli    schedule 25.09.2009

Вы не упускаете сути MVC. MVC естественным образом разбивается на уровни. Модель (DAL), контроллер (BLL), View (презентация). Они могут входить в разные проекты, если хотите, но поскольку у контроллера есть вся бизнес-логика, вам нужно только получить доступ к RoleProvider там.

Затем примените шаблоны, такие как репозиторий, шаблон и т. Д., Чтобы разделить дальше, если хотите.

Дэви

person Davy    schedule 26.09.2009
comment
Я понимаю концепцию MVC, но если я настрою BLL для проверки ролей, то почему возможность [Authorize (Roles = SomeRoleName)] из пользовательского интерфейса? - person Jay; 28.09.2009
comment
@jay Атрибут Authorize используется в контроллере, как сказал Дэви, это будет бизнес-уровень. Я думаю, что он ведет к тому, что вы, кажется, игнорируете тот факт, что слои уже были разделены шаблоном MVC. Я думаю, все зависит от того, как вы реструктурируете это решение. Джей, не могли бы вы сделать диаграмму, чтобы показать нам, как вы это разрабатываете? - person dmportella; 28.09.2009
comment
Схема поможет. Вы имеете в виду возможности пользовательского интерфейса, как в представлении? Если вы это сделаете, я думаю, что хорошо иметь просто тупой HTML, но у вас есть представление, в котором вы хотите показать что-то на основе ролей, таких как «авторизованный флажок», который только супервизоры могут видеть в другом общем представлении. Так что, на мой взгляд, возможность доступа к ролям здесь полезна. - person Davy; 02.10.2009

Вызов MVC-контроллера «UI» неуместен. «C» в MVC является частью вашего BLL, даже если он ссылается на классы, которые вы вызываете BLL. Однако вопрос не в этом.

Думаю, я бы решил эту проблему, задав вопрос: «Существует ли реальное требование для 100% разделения вашего приложения« UI »и вашего« BLL »?». Если оба компонента зависят от поставщиков членов / ролей, пусть это будет так и приступайте к работе.

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

Я думаю, что ответ Джо выше имеет большой смысл ...

person misteraidan    schedule 28.09.2009
comment
Не уверен, что контроллер является частью вашего BLL, на самом деле, я думаю, что он не должен содержать никакой бизнес-логики, просто оркестровку между вашими объектами домена. - person David Kiff; 28.09.2009
comment
В любом случае, WTF - это бизнес-логика? Все приложение представляет собой бизнес-логику, состоящую из различных компонентов бизнес-логики ... часть логики UI, часть логики MVC ... цель - правильно спроектировать и абстрагировать код, а не применять общие имена для сложных компонентов. . Идея этих прямых линейных слоев вверх и вниз глупа. Диаграмма решения - это сложная карта объектов, и работа с перекрестными объектами - наша работа. Проблема Джея - хорошая, справиться с перекрестными зависимостями будет забавной задачей. Я все еще думаю, что ответ Джо имел наибольший смысл, и теперь Я просто разглагольствую. - person misteraidan; 15.10.2009

Я думаю, что ты делаешь нормально.

Авторизация и аутентификация должны находиться на уровне служб, который, возможно, передается в ваши контроллеры.

Если контроллер устанавливает принципала и личность, а затем вы используете это в контроллере с помощью атрибутов MVC, это звучит как хорошая идея.

Было бы неплохо скрыть вашего провайдера членства MVC за интерфейсом, чтобы вы могли поменять его на провайдера членства WinForms (например) и иметь возможность проводить модульное тестирование своих контроллеров.

person David Kiff    schedule 28.09.2009

Ролевой доступ обычно не должен находиться в BLL. Доступ - это ответственность пользовательского интерфейса.

С учетом сказанного, используйте интерфейс IPrinciple, как указано на плакатах выше. У вас есть доступ к IPrinciple на уровне потока.

Thread.CurrentPrincipal
person Chuck Conway    schedule 19.09.2009
comment
Чарльз, спасибо за ответ. Как вы можете видеть, мне нужно обработать некоторую бизнес-логику, кроме базовой проверки ролей, чтобы определить истинную безопасность пользователей. Я решил, что все BL должны быть в BLL, поэтому я планировал инкапсулировать безопасность и там. Вы говорите, что предпочтительнее, чтобы указанный выше IsRoleEditor находился на моем уровне пользовательского интерфейса, а не в BLL? - person Jay; 20.09.2009
comment
-1 Я не согласен: авторизация (будь то доступ к ролям или какой-то другой механизм), безусловно, является обязанностью BLL. Уровень пользовательского интерфейса может работать на клиенте (например, Winforms), поэтому его можно скомпрометировать. - person Joe; 26.09.2009
comment
На самом деле все зависит от того, как вы разрабатываете это приложение. Приведите нам пример вашего решения, что-нибудь простое, просто названия проектов и то, как они ссылаются друг на друга. - person dmportella; 28.09.2009
comment
@ Джо, я с тобой не согласен. Ввод авторизации в пидгон BLL позволяет вам использовать эту реализацию авторизации для всего приложения и его представлений. Предполагается, что веб-службы, формы Win, веб-формы, REST API и т. Д. Должны иметь одинаковую авторизацию. Эта идея полна проблем. Рассмотрите возможность использования AD (Active Directory). AD отлично работает с WinForms, но не работает ни с чем в Интернете. Если авторизация должна использоваться в BLL, я бы окружил ее абстракцией, возможно, шаблоном провайдера. - person Chuck Conway; 06.10.2009
comment
Чарльз здесь имеет смысл. Вы не можете ожидать, что BLL волшебным образом сделает все. Приложение состоит из всех этих компонентов, и каждый компонент имеет свои собственные требования к безопасности. Включая пользовательский интерфейс, BLL, базу данных, сервер и любые вызываемые вами веб-службы. - person misteraidan; 15.10.2009