Implementing security policy for your applications (part 1)
20-01-2005 14:47
к комментариям - к полной версии
- понравилось!
Не могу сказать, чтобы я до конца понимал CAS, поэтому этот post останется (пока) на уровне "так принято". До kibitzing мой CAS еще не поднялся.
Итак, главное, что необходимо понимать для поддержки собственного security policy, это "the result of running a body of evidence through a security policy is a permission set". Т.е. CLR предлогает следующих путь :
a) ваш app читает security policy definition из своего XML,
b) грузит(load) assembly, кот. нужно проверить,
c) получает его evidence ( или вместо b) и c) создает evidence по assembly codebase )
d) пропускает этот evidence через прочтенный security policy.
Важно помнить, что в CLR security policy определяется на 4-х уровнях (levels) : User, Machine, Enterprise, AppDomain. Первые три уровня загружаются автоматически при старте CLR. Редактировать их можно или из caspol.exe или из MMC snap-in. Для вашего приложения остался уровень AppDomain, кот. никак не загружается самим CLR, а предназначен именно для целей application security policy. Первоначальный XML с вашим security policy definition лучше всего скопировать из существующих (security.config - для Machine level, enterprise.config - для Enterprise level).
Вот как может выглядеть ваш код, кот. исполняет первый шаг - а) чтение из своего XML:
PolicyLevel polLevel = SecurityManager.LoadPolicyLevelFromFile(@"...xxx.xml", PolicyLevelType.AppDomain);
Как видим, всю работу по разборке и загрузке соответствующих внутренних классов производит SecurityManager. Это довольно непростой процесс, учитывая то, как устроены отношения внутри security policy - CodeGroups со своими membership conditions etc. Возможно, это тема для отдельного post'a.
[ комментарий за 24.01
CodeGroups определяются иерархически, позволяя присвоить одному assembly различные PermissionSets. Каждый CodeGroup имеет двоякое предназначение - с одной стороны, он связывает controlled assembly(ies) с PermissionSet, а с другой - он использует интерфейс IMembershipCondition для проверки принадлежности controlled assembly к этому CodeGroup. IMembershipCondition имеет метод Check(), которым и дается эта проверка. Имплементация Check() очень разнится в зависимости от класса, кот. реализовывает IMembershipCondition. Например, UrlMembershipCondition использует URL from evidence для этой проверки, тогда как, например, StrongNameMembershipCondition делает это с помощью testing its strong name. Обратим внимание и на AllMembershipCondition class that simplu that matches all code.
Среди наиболее часто используемых реализаций CodeGroup, нужно обратить внимание на UnionCodeGroup class, that represents a code group whose policy statement is the union of the current code group's policy statement and the policy statement of all its matching child code groups. Все implementations of CodeGroup используют abstract class (not interface) CodeGroup
]
Пока же первый шаг выполнен - ваш security policy прочитан и загружен.
[комментарий за 24.01
Для поддержки permission serialization to and from XML, существует интерфейс ISecurityEncodable, со своими ToXml() и FromXml() методами.
]
Загрузка проверяемого assembly для шага не представляет никакого труда:
Assembly assm = Assembly.LoadFrom(@"....dll");
Равно, как и получение его evidence:
Evidence evidence = assm.Evidence;
Остался последний шаг - пропустить его через полученный на первом шаге policy level. И здесь код не вызывает много вопросов:
PolicyStatement statement = polLevel.Resolve(evidence);
PermissionSet permSet =statement.PermissionSet;
Тот же Resolve() имеется и у CodeGroup, позволяя пропустить evidence через policy только частично.
Кстати, то же самое можно сделать, и не загружая самого assembly, если уметь построить evidence по codebase:
Evidence evidence = new Evidence();
evidence.AddHost(new Url(codebase));
evidence.AddHost(Zone.CreateFromUrl(codebase));
try{
evidence.AddHost(Site.CreateFromUrl(codebase));
}
catch(ArgumentException} { ... }
PolicyStatement statement = polLevel.Resolve(evidence);
Относительно PolicyStatement надо сказать еще несколько слов. Этот класс нужен из-за того, что итоговый (final) PermissionSet должен еще вычисляться, принимая во внимание, на каком уровне вложенности находится соответсвующий CodeGroup. Final PermissionSet дается только при условии
PolicyStatement.Attribute == PermissionStatementAttribute.LevelFinal
SecurityManager имеет статический метод ResolvePolicy(), кот. решает этот вопрос сразы для всех уровней:
Permissionset ps = SecurityManager.ResolvePolicy(evidence);
Обратим внимание, это этот метод уже возвращает именно искомый и окончательный (final) PermissionSet.
вверх^
к полной версии
понравилось!
в evernote