发出声明性安全特性

从功能角度看,针对动态程序集及其类型和方法发出声明性安全特性,等效于针对 Ilasm.exe(MSIL 汇编程序) 编码 .permission 和 .permissionset 声明,或在 Visual Basic、C# 或 C++ 的源代码中应用 PermissionSetAttribute 特性。 但是,在用于存储所发出特性的元数据格式和用于存储所编译特性的格式之间,存在着一些区别,具体取决于 .NET Framework 的版本。

声明性安全的元数据格式

在 2005 版本中,除原始的 XML 格式外,ECMA 标准还引入了一种用于存储声明性安全特性的新的元数据格式。 有关详细信息,请参阅 ECMA 第二部分文档中 DeclSecurity 表(2005 修订版的 22.11 节)中 PermissionSet blob 的说明。 该文档可联机获得;请参见 MSDN 上的 ECMA C# and Common Language Infrastructure Standards(ECMA C# 和公共语言基础结构标准)和 Ecma International 网站上的 Standard ECMA-335 - Common Language Infrastructure (CLI)(标准 ECMA-335 - 公共语言基础结构 (CLI))。

在 .NET Framework 的所有版本中,使用反射发出应用的声明性安全是以旧的元数据格式存储的。

在 .NET Framework 2.0 版本中,使用 Ilasm.exe(MSIL 汇编程序) 和语言编译器编译的代码中的声明性安全权限以新格式存储。

在 .NET Framework 1.0 和 1.1 版本中,使用 Ilasm.exe(MSIL 汇编程序) 和语言编译器编译的代码中的声明性安全权限以旧格式存储。

发出声明性安全特性

可以针对程序集、类型、方法和构造函数发出声明性安全特性。 对于所有其他成员类型,声明性安全是针对基础方法发出的。

重要说明重要事项

以下方法无法发出声明性安全特性:创建 PermissionSetAttribute 对象,然后使用 SetCustomAttribute 方法将其应用于动态程序集、类型或方法。

  • 要针对动态程序集发出声明性安全,请创建包含必要权限、可选权限和拒绝权限的独立 PermissionSet 对象。 将这些权限设置传递给 DefineDynamicAssembly 方法的适当重载。 如果没有某个类别的应用权限,请将该参数指定为 null。

    重要说明重要事项

    除非您保存了动态程序集并将其重新加载到内存中,或使用了指定证据和所请求权限的 DefineDynamicAssembly 方法的重载,并提供了 Evidence 对象,否则不会使用必选权限、可选权限和拒绝权限。有关更多信息,请参见 DefineDynamicAssembly

  • 要针对动态程序集中的类型、方法和构造函数发出声明性安全,请创建一个包含要应用的每个 SecurityAction 所对应权限的 PermissionSet 对象。 应用权限时,对类型使用 TypeBuilderAddDeclarativeSecurity 方法,对构造函数使用 ConstructorBuilderAddDeclarativeSecurity 方法,对方法使用 MethodBuilderAddDeclarativeSecurity

    注意注意

    使用 DynamicMethod 类定义的动态方法不支持声明性安全。

  • 要针对其他所有属性和事件发出声明性安全,请使用 MethodBuilderAddDeclarativeSecurity 方法将所需权限集应用于基础方法。 例如,要为某个属性发出声明性安全,请将声明性安全应用于该属性的 get 和 set 访问器方法。

在开发负责发出动态程序集的代码时,建议使用指定了证据和权限的 DefineDynamicAssembly 方法的重载,提供您希望该动态程序集拥有的证据,并将 SecurityPermissionFlag.SkipVerification 包括在 refusedPermissions 中。 拒绝 SkipVerification 可确保 MSIL 经过了验证。 这个技术的局限性在于,当与要求完全信任的代码一起使用时,它会导致引发 SecurityException

请参见

参考

DefineDynamicAssembly

ConstructorBuilder

TypeBuilder

MethodBuilder

PermissionSet