如何实现Exception.. net 4中的GetObjectData在一个具有AllowPartiallyTrust
本文关键字:一个 AllowPartiallyTrust GetObjectData 何实现 实现 Exception net 中的 | 更新日期: 2023-09-27 17:50:20
我有一个包含自定义异常类的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);
你已经自己回答了问题的第一部分。您的程序集被加载为安全透明的,因为它没有被加载为完全信任,所以SecurityCritical
属性被忽略。这样就得到了异常
您应该处理SerializeObjectState事件,而不是重写GetObjectData
,并创建一个实现ISafeSerializationData的类型来存储用于序列化的异常状态。
除了完全可信的代码,你不能从任何地方调用带有securitycritical属性的代码:
SecurityCriticalAttribute相当于对full的链接需求信任。带有SecurityCriticalAttribute标记的类型或成员可以只能由完全可信的代码调用;它不需要要求特定的权限。它不能被部分信任的代码调用。
好吧,我知道这篇文章是相当老,但从我最近的观察,如果你不给一个程序集FullTrust在沙盒AppDomain
,所有的代码在加载程序集将是安全透明的。这意味着应用于MyException.GetObjectData
的SecurityCriticalAttribute
将什么也不做。它将是securitytransparent,并且肯定不会与它的基本方法SecurityCritical兼容。
希望这个技巧会有所帮助。
请参阅https://learn.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox了解如何将沙盒AppDomain
中的某些程序集标记为FullyTrusted。