none
Организация настраиваемых прав доступа в ASP.NET MVC RRS feed

  • Общие обсуждения

  • Во всех руководствах по MVC, когда речь заходит о правах доступа, упоминается про авторизацию на основе Ролей. При этом авторы используют фильтр Authorize[] и ограничения доступа для Users и Roles.

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

    Вторая проблема, с которой рано или поздно приходится сталкиваться, - селективное отображение данных, а точнее отображение только тех данных, которые позволены данной роли. Может, фраза сформулирована не очень понятно, поэтому поясню на примере. Пусть у нас есть на сайте раздел "Новости" (вполне стандартная ситуация). Допустим, я захожу в роли незарегистрированного пользователя или с ролью просто "Зарегистрированный пользователь". Я вижу список новостей, утвержденный и одобренный администраторами или модераторами сайта. Если же я захожу на сайт с ролью хотя бы "Модератор", то я должен увидеть не только опубликованные новости, но и те, которые еще не были опубликованы или, допустим, были скрыты по какой-либо другой причине. Возникает вопрос, как это реализовать. Ну, допустим, в сервисном слое будем проверять на наличие роли пользователя и в зависимости от этого формировать список тех же новостей. Опять это жесткое кодирование!

    И третья проблема, которая вытекает из первых двух, заключается вот в чем. Основанная на ролях авторизация не позволяет задавать уровень доступа к объекту системы. А это может потребоваться, когда админу или модератору наравне со списком тех же новостей необходимо дописывать ссылки с действиями для каждой новости, которые он может выполнить. Например: "Редактировать", "Удалить". Да и в конце концов, "Опубликовать". Ну или при переходе (в том числе и несанкционированном) необходимо, чтобы фильтр авторизации проверял уровень доступа для данного объекта. Т.е. если я выбираю действие, например, "Редактировать" (/News/Edit/4545), то впустить на эту страницу система должна только при наличии именно права Редактирования новости. Если есть доступ на просмотр и удаление новости (несколько вымышленная ситуация, но реалистичная сама по себе), но нет права на редактирования, то до свидания!

    Много искал в интернете решения этой проблемы. Ближайшее, что нашел - Claim Based Security (про CBS даже руководство от Best Practics&Patterns есть). Очень часто в примерах его прикручивают к службам WCF. Безопасность в данной случае основывается на так называемых требованиях (Claim), которые можно гибко настраивать, насколько я понял. Другой вопрос, что как-то я не догоняю, как этими требованиями пользоваться. Как перенести составляющие Claim (а именно, ClaimType, Resource и Right) на понятия в MVC (например, раздел Новости, Уровень доступа, степень отображения (все, только опубликованные и тому подобное) и т.д.).

    Из-за этого я не могу оценить, насколько это схема удовлетворяет тем потребностям, которые я описал выше. Прошу помочь разобраться в этом вопросе.

    Ссылки по теме:

    11 марта 2011 г. 5:35

Все ответы

  • Заранее прошу прощения за, быть может, некрасивый поступок, но очень хочу апнуть топик, чтобы еще раз обратить внимание общественности.

    У меня ровно такая же проблема, и я не могу придумать никакого лучшего решения, кроме как изобретать самому третий уровень абстракции, назвав его, допустим, Permissions. После этого на каждый конкретный Action (или контроллер целиком) мы навешиваем permission, а из интерфейса каждой роли выдаем список разрешенных permissions. Преимущество перед стандартным механизмом "юзер-роль" в том, что пермишены довольно статичны и их не нужно будет редактировать, а изменение прав ролей может понадобиться в любой момент.

    Написать самому это не очень сложно, но придется отказаться от таких удобных штук, как автоматическое сохранение пользователей/ролей в базе данных, и управлять этим всем вручную. Также я предполагаю, что написав собственный механизм хранения пользователей/ролей не получится красиво редактировать их через интерфейс IIS.

    Быть может этот велосипед кто-то уже придумал? Штука ведь довольно тривиальная.

    18 июня 2011 г. 17:57