Иллюстрированный самоучитель по Architecture .NET

Защита .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");
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.