【发布时间】:2026-02-19 12:40:01
【问题描述】:
我有一个标有AllowPartiallyTrustedCallersAttribute 的程序集,其中包含一个自定义异常类。我想通过覆盖GetObjectData 使其可序列化。
在 .NET 4 中,GetObjectData 已成为 SecurityCritical 方法。这意味着覆盖也需要为SecurityCritical。由于我的程序集标有AllowPartiallyTrustedCallersAttribute,因此除非另有说明,否则其中的所有代码都自动为SecurityTransparent。因此,我将 SecurityCriticalAttribute 应用于 GetObjectData 覆盖:
using System;
using System.Runtime.Serialization;
using System.Security;
[assembly:AllowPartiallyTrustedCallers]
namespace Library
{
[Serializable]
public class MyException : Exception
{
public string String;
public MyException ()
{
}
protected MyException (SerializationInfo info, StreamingContext context)
: base(info, context)
{
String = info.GetString ("String");
}
[SecurityCritical]
public override void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
info.AddValue ("String", String);
base.GetObjectData (info, context);
}
}
}
这在完全信任的情况下运行良好,例如,当我从桌面运行链接此程序集的代码时。
但是,当我从安全沙箱(见下文)使用这个类时,我得到一个TypeLoadException:
覆盖成员时违反了继承安全规则: 'Library.MyException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'。安全 覆盖方法的可访问性必须与安全性相匹配 被覆盖的方法的可访问性。
我的问题:
- 为什么会出现此异常?我确实将覆盖标记为
SecurityCritical,那么问题出在哪里? - 由于
SecurityCriticalAttribute在我的沙箱中被忽略,此类在其他部分信任主机(例如 IIS/ASP.NET 或 SQL Server)中的行为如何? - 如何在 .NET 4 中实现可序列化的异常类?
沙盒代码:
var evidence = new Evidence();
evidence.AddHostEvidence (new Zone (SecurityZone.Internet));
var setupInfo = AppDomain.CurrentDomain.SetupInformation;
var permissionSet = SecurityManager.GetStandardSandbox (evidence);
permissionSet.AddPermission (new ReflectionPermission (ReflectionPermissionFlag.MemberAccess));
permissionSet.AddPermission (new SecurityPermission (SecurityPermissionFlag.ControlEvidence));
var sandbox = AppDomain.CreateDomain ("Sandbox", evidence, setupInfo, permissionSet);
【问题讨论】: