Emitting Declarative Security Attributes
Emitting declarative security attributes for dynamic assemblies and for their types and methods is functionally equivalent to coding the .permission and .permissionset declarations for the Ilasm.exe (MSIL Assembler), or to applying the PermissionSetAttribute attribute in source code for Visual Basic, C#, or C++. However, there are differences between the metadata format used to store emitted attributes and the format used to store compiled attributes, depending on the version of the .NET Framework.
A new metadata format for storing declarative security attributes was introduced in the 2005 revisions to the ECMA standard, in addition to the original XML format. For details, see the description of the PermissionSet blob in the DeclSecurity table (section 22.11 in the 2005 revisions) in the ECMA Partition II documentation. The documentation is available online; see ECMA C# and Common Language Infrastructure Standards on MSDN and Standard ECMA-335 - Common Language Infrastructure (CLI) on the Ecma International Web site.
In all versions of the .NET Framework, declarative security applied using reflection emit is stored in the old metadata format.
Declarative security permissions in code compiled using the Ilasm.exe (MSIL Assembler) and language compilers in the .NET Framework version 2.0 are stored in the new format.
Declarative security permissions in code compiled using the Ilasm.exe (MSIL Assembler) and language compilers in the .NET Framework versions 1.0 and 1.1 are stored in the old format.
Declarative security attributes can be emitted for assemblies, types, methods, and constructors. For all other member types, declarative security is emitted for the underlying methods.
You cannot emit declarative security attributes by creating PermissionSetAttribute objects and applying them to the dynamic assembly, type, or method by using the SetCustomAttribute method.
To emit declarative security for a dynamic assembly, create separate PermissionSet objects containing the permissions that are required, optional, and refused. Pass these permission sets to the appropriate overload of the DefineDynamicAssembly method. If there are no permissions to apply for a category, specify null for that parameter.
The required, optional, and refused permissions are not used unless the dynamic assembly has been saved and reloaded into memory, or unless you use an overload of the DefineDynamicAssembly method that specifies evidence as well as requested permissions, and supply an Evidence object. For more information, see DefineDynamicAssembly.
To emit declarative security for types, methods, and constructors in a dynamic assembly, create a PermissionSet object containing the permissions for each SecurityAction you want to apply. Apply the permissions using the AddDeclarativeSecurity method of TypeBuilder for types, the AddDeclarativeSecurity method of ConstructorBuilder for constructors, and the AddDeclarativeSecurity of MethodBuilder for methods.
Declarative security is not supported for dynamic methods defined using the DynamicMethod class.
To emit declarative security for all other properties and events, apply the desired permission sets to the underlying method or methods by using the AddDeclarativeSecurity method of MethodBuilder. For example, to emit declarative security for a property, apply declarative security to the property's get and set accessor methods.
During development of code that emits dynamic assemblies, it is recommended that you use an overload of the DefineDynamicAssembly method that specifies evidence and permissions, supply the evidence you want the dynamic assembly to have, and include SecurityPermissionFlag.SkipVerification in refusedPermissions. Refusing SkipVerification ensures that the MSIL is verified. A limitation of this technique is that it also causes SecurityException to be thrown when used with code that demands full trust.