Одна проблема, с которой я сталкиваюсь регулярно и пока не могу решить, - это ограничить или разрешить доступ к определенным объектам в системе. Некоторые компании (например, банки) имеют очень строгую политику в отношении того, какие сотрудники могут получать доступ к определенной информации. Например, сотрудник определенного филиала может получить доступ к информации об учетных записях клиентов этого конкретного филиала, но не из других филиалов. Кроме того, на банки, имеющие отделения во многих странах, могут распространяться правовые ограничения, которые ограничивают доступ сотрудников в других странах к информации о местных клиентах.
Другой пример, с которым я столкнулся, - это общедоступный веб-сайт, на котором пользователи принадлежат к определенному объекту (например, компании) и могут получать доступ к информации только об этом субъекте, а не о других объектах.
Если количество объектов небольшое и фиксированное, это не проблема. Просто укажите группы домена в активном каталоге (если вы работаете в средах Microsoft, как в моем случае), добавьте пользователей в группы и ограничьте доступ с помощью IsInRole () для каждого объекта. Поэтому, если в системе есть компания под названием ABC, я бы создал группу домена под названием «Admins_ABC» или что-то в этом роде, и когда пользователь пытается управлять информацией об ABC, я бы удостоверился, что пользователь является членом этой группы. . На самом деле AD не предназначен для использования, но для небольшого числа объектов я счел это разумным.
Сложность возрастает, когда количество сущностей часто меняется и когда требования становятся более подробными. Я видел требования безопасности, которые аналогичны безопасности в NTFS - некоторые пользователи (или группы пользователей) должны иметь доступ к некоторым объектам (файлам в NTFS) или группам объектов (разрешения, установленные для каталогов в NTFS, распространяются детям).
Я стараюсь избегать подобных ситуаций, потому что они, как правило, являются кошмаром для моделирования и программирования и обычно становятся сложными в администрировании, но клиентам, с которыми я работаю, часто требуются решения этой проблемы.
Как я уже сказал, я никогда не решал эту проблему способом хорошо. Как вы подойдете к моделированию и разработке решения этой проблемы таким образом, чтобы его можно было использовать повторно? Знаете ли вы какие-либо общие проприетарные решения, которые можно использовать?





Вы изучали модель Безопасность доступа кода, которую Microsoft создала для платформы .NET? Я сам смотрел на него лишь несколько раз, но суть в том, что вы можете заблокировать определенные объекты и методы, чтобы только пользователи из внутренних сетей могли вызывать этот код. Или аналогично, метод, который выполняет обслуживание, может быть вызван только с самой машины, на которой установлен код, что не позволяет третьей стороне взломать процедуру обслуживания.
Википедия дает хорошее резюме CAS:
Code Access Security (CAS), in the Microsoft .NET framework, is Microsoft's solution to prevent untrusted code from performing privileged actions. When the CLR loads an assembly it will obtain evidence for the assembly and use this to identify the code group that the assembly belongs to. A code group contains a permission set (one or more permissions). Code that performs a privileged action will perform a code access demand which will cause the CLR to walk up the call stack and examine the permission set granted to the assembly of each method in the call stack. The code groups and permission sets are determined by the administrator of the machine who defines the security policy.
эта статья из 15 Seconds дает хороший и быстрый обзор того, как начать работу.
Я несколько раз бился головой об эту стену.
Лучшее решение, к которому я пришел, - это моделировать все в древовидной иерархии, где каждый доменный класс является ветвью в дереве, а экземпляры - листьями этой ветки. Листья могут иметь прожилки, если вам нужно обезопасить части экземпляров. Каждой ветви назначены собственные действия (такие как «Чтение», «Запись», «Удалить», «Публикация»). Используйте ту же иерархию для безопасности, но затем корень становится пользователем или группой. В итоге вы получите такую структуру:
<domain> Project
|- <class> Person
| |- <instance> John
| |- <instance> Mary
|- <class> FormX
| |- <instance> John's Leave Form
...
и для применения безопасности у вас может быть группа с именем «Администраторы», которая может делать что-то с людьми:
<group> Administrators
|- <class> Person: actions (Read, Create, Update, Suspend)
и администратор офиса, который может обрабатывать формы и создавать новых людей:
<group> Office Administrator
|- <class> Person: actions (Create)
|- <class> FormX: actions (Approve, Deny)
а затем Джон может делать что угодно со своим профилем:
<user> John
|- <class> Person
| |- <instance> John: actions (Edit)
Когда я реализовал эту структуру, она использовала C# и SQL Server 2000, поэтому я мог использовать тип данных схемы XML и выполнять запросы безопасности к базе данных или [что чаще бывает] объединять профиль безопасности человека в единое дерево для определения какие права у кого-то есть на экземпляр, класс или другое (у меня были <group>, а не группы безопасности, в домене выше класса для простоты обслуживания).
Также важно включить - хотя я не проиллюстрировал это - что каждое действие было разрешением, а не логическим, где значениями разрешения были { Allow, None, Deny } с Разрешить предоставление доступа к этому глаголу, кроме случаев явного отказа, Нет, ни разрешающих, ни запрещающих, и Запрещенных. предотвращение доступа несмотря ни на что.
Преимущество, которое вы получаете от этой структуры, заключается в том, что вы можете добавлять в нее другие типы ветвей, такие как таксономия, управляемая данными, и при этом использовать тот же API.
В моей конкретной реализации я добавил настраиваемые атрибуты метаданных к методам и свойствам, и мне пришлось вызывать метод SecurityManager.Test в каждой «защищенной» функции в качестве последнего уровня авторизации (SecurityManager.Test обычно вызывается, чтобы определить, показывать или скрывать части формы, и определить, какие кнопки были видны в пользовательском интерфейсе). Теперь, когда я знаю об этом, если мне когда-нибудь придется снова реализовать то же самое, я буду использовать PostSharp для внедрения тестов безопасности в мою модель предметной области.
Да, это похоже на то, как я это реализовал, хотя ваша реализация кажется более организованной и полной. У меня была идея использовать атрибуты вместо того, что вы называете SecurityManager.Test (), но идея PostSharp великолепна! Спасибо, вы очень помогли!
Да, я знаю о безопасности доступа по коду. Однако CAS - это модель песочницы, и это не то, что я ищу.