2013-01-02 10 views
5

Ho un assembly contrassegnato con AllowPartiallyTrustedCallersAttribute che contiene una classe di eccezione personalizzata. Voglio renderlo serializzabile ignorando GetObjectData.Come implementare Exception.GetObjectData in .NET 4 in un assembly di libreria con AllowPartiallyTrustedCallersAttribute?

Con .NET 4, GetObjectData è diventato un metodo SecurityCritical. Ciò significa che anche le sostituzioni devono essere SecurityCritical. Poiché il mio assembly è contrassegnato con AllowPartiallyTrustedCallersAttribute, tutto il codice all'interno è automaticamente SecurityTransparent se non diversamente specificato. Pertanto, applico la SecurityCriticalAttribute per l'override 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); 
    } 
    } 
} 

Questo funziona bene in scenari di fiducia piena, per esempio, quando si esegue il codice che collega questa assemblea dal mio desktop.

Tuttavia, quando uso questa classe da una sandbox di sicurezza (vedi sotto), sto diventando un TypeLoadException: regole di sicurezza

Inheritance violati, mentre l'override membro: 'Library.MyException.GetObjectData (Sistema .Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext) '. La sicurezza accessibilità del metodo di sovrascrittura deve corrispondere all'accessibilità della sicurezza del metodo sottoposto a override.

Le mie domande:

  • Perché mi appare questa eccezione? Ho contrassegnato l'override come SecurityCritical, quindi dov'è il problema?
  • Poiché lo SecurityCriticalAttribute viene ignorato nella sandbox, come si comporterebbe questa classe in altri host di attendibilità parziale, come IIS/ASP.NET o SQL Server?
  • Come si implementa una classe di eccezione serializzabile in .NET 4?

Codice Sandboxing:

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); 

risposta

1

Hai già risposto tu stesso alla prima parte della tua domanda. Il tuo assembly viene caricato come sicurezza trasparente perché non viene caricato con piena attendibilità, quindi l'attributo SecurityCritical viene ignorato. E così ottieni l'eccezione.

Invece di ignorare GetObjectData, è necessario gestire l'evento SerializeObjectState e creare un tipo che implementa ISafeSerializationData per memorizzare lo stato di eccezione per la serializzazione. Questi esistono per questo scenario esatto.

1

Non si può chiamare il codice contrassegnato con il securitycriticalattribute da qualsiasi cosa ma il codice completamente attendibile:

Il SecurityCriticalAttribute equivale ad una richiesta di collegamento per piena fiducia . Un tipo o membro contrassegnato con SecurityCriticalAttribute può essere essere chiamato solo dal codice completamente attendibile; non deve richiedere autorizzazioni specifiche . Non può essere chiamato da codice parzialmente attendibile.

C'è una domanda correlata here che parla dell'uso di securitysafecriticalattribute.

+1

In realtà, non chiamo il membro SecurityCritical ('GetObjectData'), voglio solo sovrascriverlo senza violare le" regole di sicurezza dell'ereditarietà ". Non è possibile all'interno di un assemblaggio parzialmente affidabile? –

+0

Non penso che il tuo override sia ancora contrassegnato con l'attributo. Sembra che l'attributo securitysafecritical ti possa ottenere quello che vuoi, comunque. Segna il tuo override come critico di sicurezza e accessibile in sicurezza tramite codice trasparente. Dal link sopra: "Tipi e membri contrassegnati con l'attributo SecuritySafeCriticalAttribute sono accessibili da tipi e membri parzialmente attendibili." – vinny

+0

No, 'SecuritySafeCrititcal' non può essere utilizzato per sovrascrivere un metodo' SecurityCritical'. (Ho provato, con 'SecuritySafeCritical' sto ottenendo l'eccezione" regole di sicurezza dell'eredità "anche con piena fiducia.) –

1

Bene, so che questo post è piuttosto datato, ma dalla mia osservazione di recente, se non si assegna un assembly FullTrust in sandboxing AppDomain, tutto il codice nell'assembly caricato sarà SeurityTransparent. Ciò significa che lo SecurityCriticalAttribute applicato a MyException.GetObjectData non farà nulla. Sarà SeurityTransparent e sicuramente non sarà compatibile con il suo metodo di base, SecurityCritical.

Spero che questo suggerimento possa essere di aiuto.

Vedere https://docs.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox per come contrassegnare determinati assiemi in sandboxed AppDomain come FullyTrusted.

Problemi correlati