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

Класс PermissionSet

С набором разрешений можно работать, используя класс PermissionSet. Методы AddPermission и RemovePermission дают возможность добавлять в набор экземпляры класса, производного от CodeAccessPermission. Тогда методы Deny (Запретить), PermitOnly или Assert (Утвердить) можно применять не к отдельным разрешениям, а к целым их наборам. Таким образом легче указать, что разрешается компонентам и сценариям сторонних производителей. Пример PermissionSet показывает, как это делается.

Вначале мы определяем интерфейс lUserCode, который будет использоваться нашим "проверенным" кодом для доступа к некоторому коду сторонних производителей. Хотя на самом деле этот "сторонний" код обычно располагается в отдельной сборке, но, чтобы не усложнять пример, мы все поместили в одну и ту же сборку.

public _gc _interface lUserCode
// сборщик мусора – интерфейс lUserCode
{
int PotentialRogueCode();
};
public _gc class ThirdParty:
public lUserCode // класс сборщика мусора
ThirdParty: lUserCode
{
public:
int PotentialRogueCode()
{
try {
String *filename = ".\\read.txt"; // Строка
Filelnfo *file = new Filelnfo(filename); // имя файла
StreamReader *sr = file › OpenText(); // файл
String *text; // Строка
text = sr › ReadLine(); // текст
while (text!= 0)
// пока (текст!= 0)
{
Console::WriteLine(text); // текст text = sr~>ReadLine(); // текст
}
sr › Close(); }
catch(Exception *e) // Исключение
{
Console::WriteLine(e › Message); // Сообщение
}
return 0;
}
};

Наш код создаст новый экземпляр "стороннего" класса, который должен загрузить код в нашу сборку. Затем мы вызываем метод OurCode, передавая ему "сторонний" код.

static int Main()
{
ThirdParty *thirdParty = new ThirdParty;
OurClass *ourClass = new OurClass;
ourClass › OurCode(thirdParty);
return 0;
}

Теперь посмотрим на метод OurCode. Он создает набор разрешений, состоящий из неограниченных разрешений на пользовательский интерфейс и на доступ к файлам. Затем он отменяет разрешения, находящиеся в этом наборе.

void OurCode(lUserCode *code)
{
UlPermission *uiPerm = new UlPermission(
PermissionState::Unrestricted); // Неограниченный
FilelOPermission *fileIOPerm = new FilelOPermission(
PermissionState::Unrestricted); // Неограниченный PermissionSet
*ps =
new PermissionSet(PermissionState::None);
ps › AddPermission(uiPerm);
ps › AddPermission(filelOPerm);
ps › Deny();
Console::WriteLine("Permissions denied."); // "Разрешения запрещены."
return;
}

Потом вызывается "сторонний" код. После возврата из него запрет разрешения отменяется и снова вызывается "сторонний" код.

int v = code › PotentialRogueCode();
CodeAccessPermission::RevertDeny();
Console::WriteLine("Permissions allowed.");
// "Разрешения позволены."
v = code › PotentialRogueCode();

При первом вызове PotentialRogueCode выполнение кода завершается аварийно, а при. втором – успешно. Каждый фрейм в стеке может иметь только один набор разрешений для отказа. Вызывая Deny (Запретить) для набора разрешений, вы перекрываете все остальные вызовы Deny (Запретить) для этого набора в стековом фрейме.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.