Architecture Net или что такое Microsoft.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");

Объект личности выполняет реализацию интерфейса I Identity. У этого интерфейса имеется три свойства:

  • Name (имя) — строка, относящаяся к личности. Общеязыковая среда выполнения CLR получает его от операционной системы или от средства доступа, используемого для опознавания. Таким средством доступа может быть, например, ASP.NET;
  • IsAuthenticated — логическое значение, указывающее, был ли пользователь опознан;
  • AuthenticationType — строка, которая указывает, какое опознавание использовалось операционной системой или средством доступа. Типами опознавания являются, например, Basic (Основной), NTLM, Kerberos (Цербер), Forms (Формы) или Passport (Паспорт).

Есть несколько типов объектов личности. Поскольку это Windows-программа, то имеется объект Windowsldentity, связанный с WindowsPrincipal. Вот пример, при выполнении которого распечатывается информация о свойствах объекта личности. На печать выводятся имя пользователя текущего потока и тип используемого опознавания.

Ildentity *ii = ip->Identity; Console::WriteLine(
"Thread::CurrentPrincipal Name: {0} Type: {1}
I/ Поток:: Имя {0} Тип: {1}
IsAuthenticated: {2}", ii->Name, // Имя ii->AuthenticationType, _box(ii->IsAuthenticated));

Вот что распечатывается на моей машине:

Thread::CurrentPrincipal Name: HPDESKTOPXAdministrator
Type: NTLM IsAuthenticated: True

Перевод такой:

Имя Поток::CurrentPrincipal: HPDESKTOPXAdministrator
Тип: NTLM IsAuthenticated: Истина

Подстановка имени вашей машины в примерах

В нескольких примерах используется такое имя машины, как HPDESKTOP. Запуская примеры на своем компьютере, вы можете подставлять имя соответствующей машины или соответствующего домена.
Работающая на машине операционная система использовала для опознавания протокол NTLM. Пользователь, запустивший программу, был опознан как "Administrator" ("Администратор"). Затем программа проверяет, действительно ли он является объектом Windows Identity. В этом объекте есть и другие свойства и методы, а не только те, что находятся в интерфейсе I Identity. Одним из членов Windows Identity является идентификатор лексемы учетной записи для Win32. Это идентификатор пользователя выполняемого потока.

// получить информацию от личности из WindowsPrincipal Windowsldentity *wi =
dynamic_cast<Windows!dentity *>(wp->Identity); if (wi != OY
Console::WriteLine(
"WindowsPrincipal Identity Name: {0} Type: {1}
Authenticated: {2} Token: {3}",
// Опознан: {2} Лексема: {3} ",
wi->Name, // Имя
wi->AuthenticationType,
_box(wi->IsAuthenticated),
_box(wi->Token)); // Лексема

Зная имя пользователя, можно решать программным путем, есть ли у пользователя право производить некоторые операции, не выполняя при этом те или иные ветви кода. (Иначе говоря, зная имя пользователя, можно определить полномочия.) Это показано в примере RoleBasedSecurity с помощью оператора условного перехода if-else.

// имя пользователя используется для разрешения
// выполнения ветви кода
String * name = wp->Identity->Name; // Строка - Имя
if (name->Equals("HPDESKTOP\\Administrator"))
// если (имя-> Равняется ("HPDESKTOP \\ Администратор"))
{
Console::WriteLine(
"Name matches HPDESKTOP\\Administrator");
// "Имя равно HPDESKTOP \\ Администратор"
// разрешить выполнение ветви кода, которая идет сюда...
}
else
{
Console::WriteLine(
"Name does not match HPDESKTOP\\Administrator") ;
// "Имя не равно HPDESKTOP \\ Администратор"
// не разрешить выполнение ветви кода, которая идет сюда...
}

Далее в примере RoleBasedSecurity показано, как можно выполнять некоторые действия в зависимости от членства в роли, которая определена пользователем или является встроенной, такой, например, как Administrator (Администратор), Guest (Гость) и User (Пользователь).