Класс 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 (Запретить) для этого
набора в стековом фрейме.
|