Eine System.Security.SecurityException wird ausgelöst, wenn die System.Net.HttpWebRequest-Klasse aus einer Windows Forms-Anwendung basierend auf .NET Framework 2.0 oder 3.5 SP1 verwendet wird.

Dieser Artikel hilft Ihnen bei der Behebung der System.Security.SecurityException Probleme, die ausgelöst werden, wenn Sie die System.Net.HttpWebRequest Klasse aus einer Windows Forms-Anwendung verwenden, die auf Microsoft .NET Framework 3.5 SP1 basiert.

Ursprüngliche Produktversion:   Microsoft .NET Framework 3.5 Service Pack 1
Ursprüngliche KB-Nummer:   2512713

Problembeschreibung

Sie verwenden die System.Net.HttpWebRequest Klasse aus einer Windows Forms-Anwendung, die auf Microsoft .NET Framework 3.5 Service Pack 1 basiert, synchron. Insbesondere wird dieser Code im Haupt- oder UI-Thread ausgeführt. Ihre Windows Forms-Anwendung löst eine zeitweilige Ausnahme vom Typ aus, die eine ähnliche Meldung wie System.Security.SecurityException die folgende aufweist:

Anforderung der Berechtigung vom Typ "System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" fehlgeschlagen.

Die Ausnahme zeigt einen fehlerhaften Callstack ähnlich dem folgenden an:

0:000> !clrstack
ESP EIP
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOne(Int64, Boolean)
<<ESP>> <<EIP>> System.Threading.WaitHandle.WaitOne(Int32, Boolean)
<<ESP>> <<EIP>> System.Net.NetworkAddressChangePolled.CheckAndReset()
<<ESP>> <<EIP>> System.Net.NclUtilities.get_LocalAddresses()
<<ESP>> <<EIP>> System.Net.WebProxyScriptHelper.myIpAddress()
.........
.........
<<ESP>> <<EIP>> System.Net.WebProxyScriptHelper+MyMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallOneOfTheMembers(System.Reflection.MemberInfo[], System.Object[], Boolean, System.Object, System.Reflection.Binder, System.Globalization.CultureInfo, System.String[], Microsoft.JScript.Vsa.VsaEngine, Boolean ByRef)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.Call(System.Reflection.Binder, System.Object[], System.Reflection.ParameterModifier[], System.Globalization.CultureInfo, System.String[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.Call(System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine).........
.........
<<ESP>> <<EIP>> Microsoft.JScript.JSMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.FunctionObject.Call(System.Object[], System.Object, Microsoft.JScript.ScriptObject, Microsoft.JScript.Closure, System.Reflection.Binder, System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.Closure.Call(System.Object[], System.Object, System.Reflection.Binder, System.Globalization.CultureInfo)
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallValue(System.Object, System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine, System.Object, System.Reflection.Binder, System.Globalization.CultureInfo, System.String[])
<<ESP>> <<EIP>> Microsoft.JScript.LateBinding.CallValue(System.Object, System.Object, System.Object[], Boolean, Boolean, Microsoft.JScript.Vsa.VsaEngine)
.........
.........
<<ESP>> <<EIP>> System.Reflection.MethodBase.Invoke(System.Object, System.Object[])
<<ESP>> <<EIP>> System.Net.VsaWebProxyScript.CallMethod(System.Object, System.String, System.Object[])
<<ESP>> <<EIP>> System.Net.VsaWebProxyScript.Run(System.String, System.String)
.........
.........
<<ESP>> <<EIP>> System.Net.IWebProxyScript.Run(System.String, System.String)
<<ESP>> <<EIP>> System.Net.AutoWebProxyScriptEngine.GetProxies(System.Uri, Boolean, System.Net.AutoWebProxyState ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.WebProxy.GetProxiesAuto(System.Uri, System.Net.AutoWebProxyState ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.ProxyScriptChain.GetNextProxy(System.Uri ByRef)
<<ESP>> <<EIP>> System.Net.ProxyChain+ProxyEnumerator.MoveNext()
<<ESP>> <<EIP>> System.Net.ServicePointManager.FindServicePoint(System.Uri, System.Net.IWebProxy, System.Net.ProxyChain ByRef, System.Net.HttpAbortDelegate ByRef, Int32 ByRef)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.FindServicePoint(Boolean)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)
<<ESP>> <<EIP>> System.Net.HttpWebRequest.GetRequestStream().........
.........
<<ESP>> <<EIP>> YourApplicationFunction.....
.........
.........

Ursache

Wenn die System.Net.HttpWebRequest Klasse über den Hauptthread ausgeführt wird, bei dem es sich auch um den Benutzeroberflächenthread handelt, muss sie möglicherweise das WPAD-Protokoll (Web Proxy Automatic Detection) ausführen, um zu erkennen, ob ein Proxy zum Erreichen der Ziel-URL erforderlich ist. Während dieses System.Net Vorgangs lädt das PAC-Skript (Proxy Auto-Configuration) im Arbeitsspeicher herunter und kompiliert es und versucht, die FindProxyForURL Funktion gemäß der PAC-Spezifikation auszuführen.

Erstellt dabei System.Net eine interne Anwendungsdomäne innerhalb der Anwendung, die mit minimalen Berechtigungen ausgeführt wird, und vor allem gewährt sie dieser neuen Anwendungsdomäne keine Benutzeroberflächenberechtigung. Die Auswertung eines Proxys und das Ausführen der FindProxyForURL JavaScript-Funktion erfolgt im Kontext dieser neuen Anwendungsdomäne, und während dieses System.Net Vorgangs müssen möglicherweise mehrere Hilfsfunktionen gemäß der PAC-Spezifikation ausgeführt werden, z. B. isInNet , um den Proxy zu dnsResolve myIpAddress berechnen.

Wenn die Funktion beispielsweise ausgeführt myIpAddress System.Net wird, wird versucht, die aktuelle IP-Adresse des aktuellen Computers auszuwerten, und zu einem bestimmten Zeitpunkt muss sie möglicherweise den System.Threading.WaitHandle.WaitOne() Funktionsaufruf verwenden. Wenn diese System.Threading.WaitHandle.WaitOne() Funktion vom Haupt- oder UI-Thread aufgerufen wird, verarbeitet dieser Aufruf weiterhin Fenstermeldungen, während sie wartet.

Wenn die Fenstermeldung während des Aufrufs verarbeitet wird, führt WaitOne() die .NET Framework Common Language Runtime (CLR) eine vollständige Stapelüberprüfung durch und fordert die Ui-Berechtigung an. Wenn ein Konflikt in den Berechtigungen gefunden wird, wird ein System.Security.SecurityException Fehler ausgelöst.

Lösung

Es handelt sich hierbei um ein beabsichtigtes Verhalten.

Um dieses Problem zu umgehen, können Sie entweder asynchron zur Verwendung der System.Net.HttpWebRequest Klasse wechseln, oder Sie können dennoch den synchronen Ansatz verwenden, ihn jedoch über einen Hintergrundthread oder einen Nicht-UI-Thread ausführen. Auf diese Weise kann der Fensterprozess den UI-Thread kostenlos bearbeiten, ohne dass Warteaufrufe in einer anderen Anwendungsdomäne unterbrochen werden müssen.

Ein weiterer Ansatz, den Sie verwenden können, besteht darin, den gleichen Code wie zuvor beizubehalten. Anstatt die System.Net automatische Proxyerkennung im Hauptthread auszuführen, können Sie einen neuen Thread erstellen und versuchen, die System.Net.WebProxy.GetProxy Funktion in diesem Hintergrundthread auszuführen, und dem Hintergrundthread die automatische Proxyerkennung ermöglichen. Nachdem der Hintergrundthread die Adresse eines Proxyservers abgerufen hat, können Sie die Proxy Eigenschaft des Objekts festlegen und auf einen festen Proxy HttpWebRequest festlegen. Dadurch wird die automatische Proxyerkennung im Hauptthread verhindert und die Ausnahme nicht ausgelöst.

Wenn in Ihrer Umgebung ein fester Proxy konfiguriert ist, können Sie die automatische Proxyerkennung vollständig deaktivieren, indem Sie die folgenden Konfigurationseinstellungen in Ihrer Anwendungskonfigurationsdatei hinzufügen:

<system.net>
    <defaultProxy>
        <proxy autoDetect="False" usesystemdefault="False" proxyaddress="http://yourProxy:yourProxyPort"/>
    </defaultProxy>
</system.net>

Hinweis

Obwohl die Ausführung synchroner HTTP-Anforderungen mithilfe der Klasse in den System.Net.HttpWebRequest meisten Szenarien einwandfrei funktionieren sollte, wird davon abgeraten, synchrone Netzwerkvorgänge auszuführen, z. B. das Senden von HTTP-Anforderungen vom Haupt- oder UI-Thread aufgrund möglicher Verzögerungen bei Netzwerkvorgängen (z. B. IP-Adresse oder DNS-Auflösung, Proxyerkennung usw.). Es empfiehlt sich, solche synchronen Anforderungen aus einem Hintergrundthread auszuführen oder die Anforderungen asynchron auszuführen.

Weitere Informationen