Lab 1. PermitOnly()
Scenario : despite the external assembly has been granted the permissions (by policy config file) to call SqlConnection.Open(),such the attempt is failed because calling assembly want to restrict the caller notwithstanding policy.
1.1.1). Preparing policy config file : Create CodeGroup with URLMembershipCondition that points to the folder with assemlby to be loaded
1.1.2) Create PermissionSet includeing 2 permissions - SecurityPermission with Assertion and Execution flags and unrestricted SqlClientPermission .This will grant the assembly to be loaded the SQLConnection.Open() permissions
1.2) Load and invloke the external assembly
1.2.1). External assembly is loaded (LoadFrom) by codebase. Its evidence established and captured
Assembly assm = Assembly.LoadFrom(codebase);
Evidence evidence = assm.Evidence;
1.2.2). Policy loaded from .config file at AppDomain level. The evidence of the loaded assembly is resolved thru the policy returning "effective permission set" for this AppDomain for loaded assembly.
PolicyLevel polLevel = SecurityManager.LoadPolicyLevelFromFile(@"folknote.config", PolicyLevelType.AppDomain);
PolicyStatement statement = polLevel.Resolve(evidence);
PermissionSet ps = statement.PermissionSet;
1.3) Construct the required permission set (for Execution only)
IPermission perm = new SecurityPermission(SecurityPermissionFlag.Execution);
PermissionSet requiredPS = new PermissionSet(PermissionState.None);
requiredPS.AddPermission(perm);
1.3.1) Check if loaded asembly has been granted required Execution permissionsbool bRes = requiredPS.IsSubsetOf(ps);
1.4) Enable further running only under permitted permissions!requiredPS.PermitOnly();
1.5.1) Compile and run. Check the security exception is raised.
1.5.2) Remove the PermitOnly() call from caller. Run once again - no security exception is raised this time.
Note: security check is lazy as possible. You was eble to create new SqlConnection object but actual invocation is only checked when you call SqlConnection.Open() method.
Lab 2. Assert()
В прошлом lab'е создалась довольно абсурдная ситуация : несмотря на то, что loaded assembly has been explicitly (by policy config) granted SqlClientPermission, it was failed to actually invoke Open() method! Почему это абсурд? Потому, что с одной стороны, host, кот. хочет to tune permissions, seems to be able to ignore policy settings. From other hand, it's the primary goal of the policy files - to tune security declaratively! Such kind of absurd решается с помощью Assert().Вызывая Assert(), client states that it willing to restrict the stack walk upstream, till existing [bp]. Философски выражаясь, это можно сформулировать примерно так: я уважаю ограничения, высталенные by callers, но я все-таки хочу вызвать то, что мне надо; пусть же нас рассудит policy. А policy рассуждает так: с одной стороны, у callee есть permissions на вызов - надо бы разрешить, с другой стороны - сам caller поставил PermitOnly(), значит у него были какие-то причины? Поэтому поищем среди permissions callee - SecurityPermissions.Assert (see lab1): если стоит - разрешить Assert() и сам вызов, разумеется; если нет - администратор, видимо, лучше знает.
2.1) Insert Assert invocation into callee code:
SqlClientPermission perm = new SqlClientPermission(PermissionState.Unrestricted);
perm.Assert();
2.2) Compile, run and see success invlocation of SqlConnection.Open()
2.3) Remove Assertion from Permission section of desired PermissionSet. Run and see SecurityException raised.
Вывод: всегда включайте в код своих assemblies Assert() - пусть администратор policy сам разбирается.
Lab 3.Demand()
Lab 4.Deny()