#asp.net #sql-server #security #active-directory #roles
Вопрос:
У меня есть ASP.NET 2.0 [без ajax…пока] веб-сайт, который будет развернут в скомпилированном виде на нескольких сайтах клиентов. Как правило, сайт будет доступен только в интрасети. Некоторые клиенты доверяют всем своим сотрудникам и не заботятся об ограничении доступа к сайту и/или функциям страниц, другие не доверяют никому и хотят, чтобы только определенные люди и/или группы могли просматривать определенные страницы, нажимать определенные кнопки и т. Д.
я мог бы создать какое-нибудь домашнее решение, возможно, управлять разрешениями доступа из таблицы базы данных, но прежде чем я пойду по этому пути, я подумал, что спрошу в SO: каково хорошее решение для этой ситуации? предпочтительно тот, которым можно полностью управлять в файле web.config и/или базе данных, так как перестроить веб-сайт невозможно (для клиента, и я не хочу, чтобы это приходилось делать для них снова и снова). Интеграция с Active Directory была бы бонусом, но не обязательным требованием (если только это не проще).
в качестве отправной точки я думаю, что каждой странице/функциональной точке сайта будет присвоена идентификация и она будет связана с группой разрешений…
РЕДАКТИРОВАТЬ: раздел авторизации web.config для разрешения/запрета доступа по ролям и пользователям хорош, но это только половина проблемы — другая половина контролирует доступ к отдельным методам (кнопкам, что угодно) на каждой странице. Например, некоторые пользователи могут просматривать сообщения whatchamacallits, в то время как другим разрешено редактировать, создавать, удалять или отключать/включать их. Все эти кнопки/ссылки/действия находятся на странице просмотра…
[в идеале я бы сделал отключенные кнопки невидимыми, но здесь это не важно]
ИЗМЕНИТЬ: пока есть несколько хороших предложений, но пока нет полного решения — все еще склоняюсь к решению, основанному на базе данных…
- атрибуты требования разрешений безопасности будут создавать исключения при нажатии кнопок, что не очень удобно; я бы предпочел скрыть кнопки, которые пользователю запрещено использовать
- элемент управления LoginView также интересен, но потребует репликации большей части содержимого страницы несколько раз (по одному разу для каждой роли) и может не обрабатывать случай, когда пользователь находится в более чем одной роли — я не могу предположить, что роли являются иерархическими, поскольку они будут определены клиентом
ИЗМЕНИТЬ: платформа Win2K/XP, Sql Server 2005, ASP.NET 2.0, не используя AJAX
Ответ №1:
Я думаю, что вам нужно здесь реализовать набор методов запроса разрешений либо в ваших бизнес-объектах, либо в вашем контроллере. Примеры: CanRead(), CanEdit(), CanDelete()
При отображении страницы необходимо запросить бизнес-объект и определить авторизованные возможности пользователей, а также включить или отключить функциональные возможности на основе этой информации. Бизнес-объект, в свою очередь, может использовать Роли или дополнительные запросы к базе данных для определения разрешений активного пользователя.
Я не могу придумать способ декларативно определить эти разрешения централизованно. Их необходимо распределить на реализацию функций. Однако, если вы хотите улучшить дизайн, вы можете использовать внедрение зависимостей для вставки авторизаторов в свои бизнес-объекты и, таким образом, сохранить отдельные реализации.
В книге Рокки Лхотки есть код, который использует эту модель. Новая версия еще не появилась в Google.
Комментарии:
1. я начал с этого подхода, но вскоре столкнулся с проблемами, поскольку не все разрешения основаны на доступе к сущностям; некоторые из них просто поведенческие и довольно произвольные.
2. смотрите изменения в моем ответе; авторизация двоичной группы объявлений плюс разрешение на функции, похоже, решают все требования
Ответ №2:
Я предпочитаю предоставлять права доступа группам объявлений, а не конкретным пользователям. Я нахожу его гораздо более гибким.
Я мало что знаю о вашем приложении, но вы, возможно, захотите взглянуть на тег авторизации в файле web.config:
<authorization>
<!--
<deny users="?" />
<allow users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
<deny users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
-->
</authorization>
Вы можете отделить файлы web.config от каждого каталога в своем веб-приложении, а также вложить каталоги. Каждый файл web.config может иметь свой собственный раздел авторизации. Если вы разместите разные страницы в каждом каталоге, вы сможете эффективно управлять безопасностью, разрешая определенную роль в каждом файле web.config и отрицая все остальное. Затем вы сможете управлять участниками каждой роли в active directory. Я обнаружил, что это эффективное решение, потому что оно эффективно использует Active Directory Microsoft и ASP.NET рамки безопасности без написания собственных пользовательских материалов, и если вы используете роли, можно передать управление членством в ролях кому-то, кому никогда не нужно касаться файла web.config, им просто нужно знать, как использовать консоль управления рекламой.
Комментарии:
1. интересный подход, но это решает только половину проблемы — некоторые пользователи могут просматривать определенную страницу, но не нажимать некоторые кнопки на этой странице…
2. принято как «ответ», поэтому страница статистики перестанет надоедать мне
Ответ №3:
Хотя я никогда раньше не использовал это на практике и не могу оспаривать его достоинства, я это знаю .NET имеет защиту кода на основе ролей, которая позволяет декларативно блокировать методы по ролям или пользователям. Например:
[PrincipalPermissionAttribute(SecurityAction.Demand, Name = "MyUser", Role = "User")]
public static void PrivateInfo()
{
//Print secret data.
Console.WriteLine("nnYou have access to the private data!");
}
Безопасность на основе ролей рассматривается более подробно здесь. Я не знаю, сильно ли это вам поможет, учитывая, что для его изменения потребуется перекомпиляция; однако наложение меток на методы быстрее, чем построение логики для отображения/скрытия кнопок или проверки безопасности в коде.
Кроме того, вы захотите ознакомиться с встроенной проверкой подлинности Windows, чтобы получить возможность использования Active Directory.
Комментарии:
1. спасибо, но атрибут требования безопасности просто создаст исключение, когда неавторизованный пользователь нажмет кнопку, что не очень «дружелюбно»…
Ответ №4:
Похоже, вы могли бы использовать элемент управления LoginView, который может отображать панели элементов управления только определенным пользователям или ролям. Роли являются наиболее гибкими — если безопасность не требуется, поместите всех пользователей во все роли.
Используйте в сочетании со стандартной безопасностью web.config (интегрированная Windows с active directory или проверка подлинности форм (схема Sql server asp 2 или ваша собственная).
<asp:LoginView id="LoginView1" runat="server">
<RoleGroups>
<asp:RoleGroup Roles="Admin">
<ContentTemplate>
<asp:LoginName id="LoginName2" runat="Server"></asp:LoginName>, you
are logged in as an administrator.
</ContentTemplate>
</asp:RoleGroup>
<asp:RoleGroup Roles="User">
<ContentTemplate>
<asp:Button id="Button1" runat="Server" OnClick="AllUserClick">
</ContentTemplate>
</asp:RoleGroup>
</RoleGroups>
</asp:LoginView>
Комментарии:
1. еще один интересный подход, спасибо, но использование этого будет означать, что мне придется несколько раз копировать большую часть html — кода для каждой страницы и не будет обрабатывать случай, когда пользователь может быть в нескольких ролях
Ответ №5:
я думаю, что мне придется объединить авторизацию рекламы с таблицами «функции и разрешения» в базе данных, чтобы получить необходимый нам четкий контроль —
- используйте файл web.config, чтобы разрешить только авторизованным пользователям (через группы объявлений) посещать веб-сайт
- составьте таблицу «функции» с перечислением каждой страницы и функции, на которые можно повлиять, например, кнопка редактирования страницы 1, кнопка удаления страницы 2, сетка сведений страницы 3 и т. Д.
- создайте таблицу «разрешения», содержащую функцию и группу объявлений, которым разрешено использовать эту функцию
- измените страницы сайта, чтобы проверить разрешения на загрузку страниц (или предварительный просмотр, в зависимости от обстоятельств), чтобы отключить/скрыть запрещенные функции в зависимости от обстоятельств
примеры:
- Администраторы могут использовать все функции сайта
- Разработчики могут использовать все функции сайта
- Менеджеры могут просматривать все страницы, но могут только добавлять и редактировать информацию, без удаления
- Руководители могут просматривать сводки по всем отделам, но просматривать и редактировать сведения только для своего отдела (для каждого отдела и отдела-руководителя есть группа объявлений).
- Сотрудники могут просматривать подробную информацию только для своего отдела
- и т.д.
Окончательное решение свело понятие «функция» к двоичному решению «можно использовать» или «нельзя использовать» и добавило флаг «разрешающий/не разрешающий» для каждой функции. Это позволяет определять функции, которые могут использовать большинство пользователей, как «разрешающие», а затем в таблице разрешений необходимо записывать только группы, которым отказано в разрешении на использование этой функции. Для функции, определенной как недопустимая, по умолчанию никто не может использовать эту функцию, и вам необходимо создать записи в таблице разрешений для групп, которым разрешено использовать эту функцию. Это, по-видимому, дает лучшее решение из обоих миров, поскольку оно уменьшает количество записей разрешений, необходимых для каждой функции.