Защита .NET на основе ролей. Принципалы и личности.
Большинство людей имеют хотя бы интуитивное представление о пользователях и паролях. В то же время сервер транзакций корпорации Microsoft (MTS) и СОМ+ поддерживают хорошо известную и легкую для понимания систему зашиты на основе ролей. Более детальное изучение защиты .NET лучше всего начинать с личностей и ролей. Сначала мы изучим этот материал, имея в виду Windows-приложения, а затем – применительно к ASP.NET.
Каждый поток связан с принципалом общеязыковой среды выполнения CLR. Принципал содержит личность, которая представляет идентификатор пользователя, запускающего поток. Текущий принципал, связанный с вызываемым потоком, является значением статического свойства Thread::CurrentPrincipal.
Объекты принципала реализуют интерфейс IPrincipal. Этот интерфейс обладает одним методом и одним свойством. Свойство Identity (Личность) возвращает текущий объект личности, а метод IsInRole используется, чтобы определять, находится ли данный пользователь в указанной роли. Использование принципалов, личностей и ролей показано в примере, который называется RoleBasedSecurity.
Сейчас в системе .NET имеется два класса принципалов: WindowsPrincipal и GenericPrincipal. GenericPrincipal полезен тогда, когда должен быть реализован ваш собственный принципал. Ну а класс WindowsPrincipal представляет пользователя Windows и связанные с ним роли.
В примере RoleBasedSecurity программа начинается с требования предоставить SecurityPermission для манипуляций с объектом принципала. Затем программа задает политику принципала AppDomain. SecurityPermission – класс разрешения, выдаваемого системой защиты. Этот класс устанавливает для разрешения определенный набор флажков. В текущем примере конструктор SecurityPermission принимает в качестве параметра Security PermissionFlag::ControlPrincipal, указывающий на возможность управлять объектом принципала.
Метод Demand (Требование) класса SecurityPermission вызывается для того, чтобы узнать, есть ли у нас разрешение, позволяющее манипулировать названным объектом принципала. Если есть, то тогда мы продолжаем менять политику этого принципала. Ну а если такого разрешения у нас нет, то Demand (Требование) запустит исключение SecurityException, и выполнение программы прекратится.
// определить право изменять политику принципала Console::WriteLine( "Demanding right to change principal policy"); // "Требование права изменять политику принципала" SecurityPermission *sp = new SecurityPermission( SecurityPermissionFlag::ControlPrincipal); try { // Проверить, всем ли вызывающим программам // выше в стеке вызовов // предоставлено разрешение управлять // объектом принципала перед работой с ним. sp › Demand(); // Запрос } catch(SecurityException *se) { //не может управлять объектом принципала Console::WriteLine(se › Message); // Сообщение return; }
Затем мы меняем политику принципала. Вместо заданной по умолчанию UnauthenticatedPrincipal задаем политику WindowsPrincipal. Это значит, что объекты принципала и личности будут создаваться на основе предоставленного пользователем операционной системы опознавательного знака текущего потока. Кроме того, это означает, что роли будут задаваться на основе групп пользователей операционной системы.
AppDomain *ap = AppDomain::CurrentDomain; ap › SetPrincipalPolicy! PrincipalPolicy::WindowsPrincipal); Console::WriteLine( "AppDomain Principal Policy changed to WindowsPrincipal"); // "Политика принципала AppDomain изменена на // WindowsPrincipal");
Далее мы получаем принципал текущего потока и проверяем, является ли он WindowsPrincipal. Так как пример RoleBasedSecurity является (консольным) Windows-приложением, то свойству CurrentPrincipal должен соответствовать класс.
WindowsPrincipal. IPrincipal *ip; ip = Thread::CurrentPrincipal; // Поток WindowsPrincipal *wp = dynamic_cast<WindowsPrincipal *>(ip); if (wp == 07 Console::WriteLine( "Thread::CurrentPrincipal is NOT a WindowsPrincipal"); // "Поток:: CurrentPrincipal – HE WindowsPrincipal"); else Console::WriteLine( "Thread::CurrentPrincipal is a WindowsPrincipal"); // "Поток:: CurrentPrincipal – WindowsPrincipal");