Microsoft KB Archive/318169

= INFO: When to Use Identity Permissions with Declarative Security vs. Imperative Security =

Article ID: 318169

Article Last Modified on 5/17/2002

-

APPLIES TO


 * Microsoft Visual Studio .NET 2002 Professional Edition

-



This article was previously published under Q318169



SUMMARY
Identity permissions control code access from one assembly to another. You can use identity permissions, which are a subset of code access permissions, either declaratively or imperatively. This article outlines some of the differences between declarative security and imperative security for identity permissions.



MORE INFORMATION
Unlike imperative security, declarative security does not require that every block of code that is on the stack must have permission settings checked against the caller. Because of this, identity permissions are more efficient with declarative security. Moreover, if you use code access permissions declaratively, the permissions are evaluated at load time or just-in-time (JIT). This is more efficient than if you use code access permissions imperatively, which evaluate the permissions at run time.

For load-time declarative security use the LinkDemand code attribute. If you apply the LinkDemand code attribute, the security is checked on the immediate caller during JIT compilation. The LinkDemand code attribute specifies what permissions the caller must have to access the code. If you try to access the code, and if you do not have the proper LinkDemand permissions, a security exception is thrown.

Imperative security uses code that is executed at run time to enforce security. At run time, when a Demand method is called from an Identity Permission class, the call stack is evaluated to verify the code. If there is a point in the call stack where assemblies that were previously called do not have the same identity as the code, exceptions are thrown.

You can initiate a Security Exception in this code sample if you create a new key file with the same name as the original key. Use the new file to overwrite the original key file. Create the new key, recompile, and then run the unchanged application. The application fails at load time because the embedded key does not match the key that is listed in the declarative attribute. Sample Code:

=
Note: Encryption keys must be generated as security evidence

1. Generate the encryption keys: sn -k Key.SNK

2. Extract the public key: sn -p Key.SNK PublicKey.SNK

3. Display the public key in hexadecimal: sn -tp PublicKey.SNK

4. Copy the text output from step 3 under the heading &quot;Public key is&quot; into the StrongNameIdentityPermissionAttribute code attribute on   the Sample Declarative class below where PublicKey = &quot;0x0024...518ce&quot;. It must be a full 320 character string (exclusive of the '0x'  hexadecimal specifier).

5. Create the following Console Application below. This code can be   compiled with the command line (assuming the code is in Class1.cs): csc /target:exe Class1.cs  Alternatively, you can create a Console Application project in    Visual C# .NET and replace the default Class1.cs file with the code specified below. Note that the AssemblyKeyFile attribute specified below will be duplicated in the default project       AssemblyInfo.cs file. You can comment out the duplicate entry in AssemblyInfo.cs (or delete  AssemblyInfo.cs from the project entirely). In a Visual Studio .NET (Visual C# .NET) project you also must change the AssemblyKeyFile path because of the project directory structure and build rules to: [assembly: AssemblyKeyFile(&quot;..\\..\\Key.snk&quot;)] // C# using System; using System.Security.Permissions; using System.Reflection; using System.Runtime.CompilerServices;

// Include the key file in the assembly [assembly: AssemblyKeyFile(&quot;key.snk&quot;)]

namespace Q318169 {

class Class1 {

[STAThread] static void Main(string[] args) { SampleImperative si = new SampleImperative; si.Verify;

SampleDeclarative sd = new SampleDeclarative; sd.Verify; }   }

// Imperative Security (code based)

public class SampleImperative {

public void Verify { Type ThisType = this.GetType; Assembly ThisAssembly = ThisType.Assembly; AssemblyName an = ThisAssembly.GetName; byte[] MyKey = an.GetPublicKey; StrongNamePublicKeyBlob KeyBlob = new StrongNamePublicKeyBlob(MyKey);

StrongNameIdentityPermission p                = new StrongNameIdentityPermission (KeyBlob,null,null);

try { // Imperative (runtime) Security 'Demand' p.Demand; Console.WriteLine(&quot;Imperative Security Verified&quot;); }           catch (System.Security.SecurityException se) { // If Demand fails execute // on the SecurityException }       }    }

// Declarative Security (attribute based)

[StrongNameIdentityPermissionAttribute (SecurityAction.LinkDemand, PublicKey = &quot;0x0024...518ce&quot;)] public class SampleDeclarative {

public void Verify { Console.WriteLine(&quot;Declarative Security Verified&quot;); }   } }

