बैकग्राउंडर: नोदा टाइम में कई धारावाहिक संरचनाएँ होती हैं। जब मैं बाइनरी सीरियलाइजेशन को नापसंद करता हूं, तो हमें इसे समर्थन देने के लिए कई अनुरोध प्राप्त हुए, 1.x समय में वापस। हम ISerializable
इंटरफ़ेस को लागू करके इसका समर्थन करते हैं ।
हमें .NET फिडल के भीतर Noda Time 2.x में विफल रहने की हालिया समस्या रिपोर्ट मिली है । Noda Time 1.x का उपयोग करने वाला समान कोड ठीक काम करता है। इस अपवाद को फेंक दिया गया है:
सदस्य को ओवरराइड करते समय इनहेरिटेंस सुरक्षा नियमों का उल्लंघन हुआ: 'NodaTime.Duration.System.Runtime.Serialization.ISerializable.GetObjectData (System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'। ओवरराइडिंग मेथड की सिक्योरिटी एक्सेसिबिलिटी ओवरराइड होने के तरीके की सिक्योरिटी एक्सेसिबिलिटी से मेल खाना चाहिए।
मैंने इसे उस फ़्रेमवर्क तक सीमित कर दिया है जो लक्षित है: 1.x लक्ष्य .NET 3.5 (क्लाइंट प्रोफ़ाइल); 2.x लक्ष्य .NET 4.5। वे PCL बनाम .NET कोर और प्रोजेक्ट फ़ाइल संरचना के समर्थन में बड़े अंतर हैं, लेकिन ऐसा लगता है कि यह अप्रासंगिक है।
मैं इसे एक स्थानीय परियोजना में पुन: पेश करने में कामयाब रहा हूं, लेकिन मुझे इसका कोई हल नहीं मिला है।
VS2017 में प्रजनन के लिए कदम:
- एक नया समाधान बनाएँ
- एक नया क्लासिक विंडोज कंसोल एप्लिकेशन बनाएं जिसका लक्ष्य .NET 4.5.1 है। मैंने इसे "कोडरनर" कहा।
- परियोजना गुणों में, साइनिंग पर जाएं और एक नई कुंजी के साथ विधानसभा पर हस्ताक्षर करें। पासवर्ड की आवश्यकता को अनटिक करें, और किसी भी कुंजी फ़ाइल नाम का उपयोग करें।
- प्रतिस्थापित करने के लिए निम्न कोड चिपकाएँ
Program.cs
। यह इस Microsoft नमूने में कोड का संक्षिप्त संस्करण है । मैंने सभी रास्तों को एक समान रखा है, इसलिए यदि आप फुलर कोड पर वापस जाना चाहते हैं, तो आपको कुछ और बदलने की आवश्यकता नहीं है।
कोड:
using System;
using System.Security;
using System.Security.Permissions;
class Sandboxer : MarshalByRefObject
{
static void Main()
{
var adSetup = new AppDomainSetup();
adSetup.ApplicationBase = System.IO.Path.GetFullPath(@"..\..\..\UntrustedCode\bin\Debug");
var permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
var fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<System.Security.Policy.StrongName>();
var newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);
var handle = Activator.CreateInstanceFrom(
newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
typeof(Sandboxer).FullName
);
Sandboxer newDomainInstance = (Sandboxer) handle.Unwrap();
newDomainInstance.ExecuteUntrustedCode("UntrustedCode", "UntrustedCode.UntrustedClass", "IsFibonacci", new object[] { 45 });
}
public void ExecuteUntrustedCode(string assemblyName, string typeName, string entryPoint, Object[] parameters)
{
var target = System.Reflection.Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint);
target.Invoke(null, parameters);
}
}
- "अनट्रस्टेडकोड" नामक एक और प्रोजेक्ट बनाएं। यह एक क्लासिक डेस्कटॉप क्लास लाइब्रेरी प्रोजेक्ट होना चाहिए।
- विधानसभा पर हस्ताक्षर; आप कोडरनर के लिए एक नई कुंजी या उसी का उपयोग कर सकते हैं। (यह आंशिक रूप से नोदा समय की स्थिति की नकल करने के लिए है, और आंशिक रूप से कोड विश्लेषण को खुश रखने के लिए है।)
- निम्नलिखित कोड पेस्ट करें
Class1.cs
(ओवरराइटिंग क्या है):
कोड:
using System;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
// [assembly: AllowPartiallyTrustedCallers]
namespace UntrustedCode
{
public class UntrustedClass
{
// Method named oddly (given the content) in order to allow MSDN
// sample to run unchanged.
public static bool IsFibonacci(int number)
{
Console.WriteLine(new CustomStruct());
return true;
}
}
[Serializable]
public struct CustomStruct : ISerializable
{
private CustomStruct(SerializationInfo info, StreamingContext context) { }
//[SecuritySafeCritical]
//[SecurityCritical]
//[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
}
}
कोडरनर प्रोजेक्ट चलाना निम्नलिखित अपवाद देता है (पठनीयता के लिए सुधारित):
अखंडित अपवाद: System.Reflection.TargetInvocationException:
अपवाद को एक मंगलाचरण के लक्ष्य से फेंक दिया गया है।
--->
System.TypeLoadException:
सदस्य को ओवरराइड करते समय इनहेरिटेंस सुरक्षा नियमों का उल्लंघन किया गया:
'UntrustedCode.CustomStruct.System.Runtime.Serialization.ISerializable.GetObjectData (...)।
ओवरराइडिंग मेथड की सिक्योरिटी
एक्सेसिबिलिटी ओवरराइड होने के तरीके की सिक्योरिटी एक्सेसिबिलिटी से मेल खाना चाहिए ।
टिप्पणी की गई विशेषताएँ उन चीज़ों को दिखाती हैं जिन्हें मैंने आज़माया है:
SecurityPermission
दो अलग-अलग एमएस लेखों ( पहले , दूसरे ) द्वारा अनुशंसित है , हालांकि दिलचस्प रूप से वे स्पष्ट / अंतर्निहित इंटरफ़ेस कार्यान्वयन के आसपास अलग-अलग चीजें करते हैंSecurityCritical
वर्तमान में नोदा टाइम क्या है, और इस प्रश्न का उत्तर क्या हैSecuritySafeCritical
कुछ हद तक कोड विश्लेषण नियम संदेशों द्वारा सुझाया गया है- किसी भी विशेषता के बिना , कोड विश्लेषण नियम खुश हैं -
SecurityPermission
या तो याSecurityCritical
वर्तमान के साथ, नियम आपको विशेषताओं को हटाने के लिए कहते हैं - जब तक आपके पास नहीं हैAllowPartiallyTrustedCallers
। दोनों मामलों में सुझावों का पालन करने से कोई मदद नहीं मिलती है। - नोडा टाइम ने इसके लिए
AllowPartiallyTrustedCallers
आवेदन किया है; यहां उदाहरण लागू विशेषता के साथ या उसके बिना काम नहीं करता है।
एक अपवाद के बिना कोड रन अगर मैं जोड़ने [assembly: SecurityRules(SecurityRuleSet.Level1)]
के लिए UntrustedCode
विधानसभा (और टिप्पणी हटाएं AllowPartiallyTrustedCallers
विशेषता), लेकिन मुझे विश्वास है कि समस्या यह है कि अन्य कोड में बाधा सकता है के लिए एक गरीब समाधान है।
मैं पूरी तरह से खो जाने की बात मानता हूँ जब यह .NET के सुरक्षा पहलू पर आता है। तो मैं .NET 4.5 को लक्षित करने के लिए क्या कर सकता हूं और फिर भी अपने प्रकारों को कार्यान्वित करने की अनुमति देता हूं ISerializable
और अभी भी .NET Fiddle जैसे वातावरण में उपयोग किया जा सकता है?
(जब मैं .NET 4.5 को लक्षित कर रहा हूं, मेरा मानना है कि यह .NET 4.0 सुरक्षा नीति में परिवर्तन है, जो इस समस्या का कारण है, इसलिए टैग।)
AllowPartiallyTrustedCallers
से चाल चलनी चाहिए, लेकिन इससे कोई फर्क नहीं पड़ता