如何在具有AllowPartiallyTrustedCallersAttribute的库程序集中的.NET 4中实现Exception.GetObjectData?

Fab*_*ied 6 c# code-access-security

我有一个标有AllowPartiallyTrustedCallersAttribute包含自定义异常类的程序集.我想通过覆盖使其可序列化GetObjectData.

使用.NET 4,GetObjectData已经成为一种SecurityCritical方法.这意味着还需要覆盖SecurityCritical.由于我的程序集标有AllowPartiallyTrustedCallersAttribute,所以SecurityTransparent除非另有说明,否则所有代码都是自动的.因此,我将应用于SecurityCriticalAttributeGetObjectData覆盖:

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这在完全信任的情况下工作正常,例如,当我运行从桌面链接此程序集的代码时.

但是,当我从安全沙箱中使用这个类时(见下文),我得到了一个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);
Run Code Online (Sandbox Code Playgroud)

Car*_*nke 2

您自己已经回答了问题的第一部分。您的程序集正在以安全透明的方式加载,因为它没有以完全信任的方式加载,因此该SecurityCritical属性将被忽略。所以你得到了例外。

GetObjectData您应该处理SerializeObjectState事件并创建一个实现ISafeSerializationData 的类型来存储序列化的异常状态,而不是重写。这些都是针对这种具体情况而存在的。