2010-04-27 11 views
10

Hoy tuve un problema extraño al intentar depurar de forma remota una aplicación creada para el tiempo de ejecución de .NET 4.0.. La aplicación .NET 4.0 en el recurso compartido de red causa SecurityException

La aplicación reside en un recurso compartido de red y la ejecuta un equipo remoto. Sin embargo, la aplicación se bloquea cada vez durante la carga debido a una SecurityException generada por una demanda de permisos en el método System.Configuration.ConfigurationManager.GetSection(). No he comprobado si otras demandas de permisos en la biblioteca de la clase base también causan una excepción de seguridad, pero en todos los casos esto no debería estar ocurriendo con el nuevo CLR.

La aplicación se ejecuta con plena confianza (comprobada durante la depuración y, como siempre, debe ser así para las aplicaciones de intranet en CLR 4.0), así que no tengo idea de cómo una solicitud de permiso puede causar una excepción en este caso. Cuando se compila con el motor de tiempo de ejecución 3.5 SP1 (que introdujo por primera vez la confianza total para las aplicaciones compartidas de red de forma predeterminada), todo funciona como se espera.

He pegado el código de muestra a continuación. Cualquier ayuda es muy apreciada.

using System; 
using System.Configuration; 

namespace ConsoleApplication1 
{ 
public sealed class AssetsSection : ConfigurationSection 
{ 
    private static readonly ConfigurationProperty   s_propPath; 
    private static readonly ConfigurationPropertyCollection s_properties; 

    static AssetsSection() 
    { 
     s_propPath = new ConfigurationProperty("path", typeof(String)); 

     s_properties = new ConfigurationPropertyCollection() 
     { 
      s_propPath 
     }; 
    } 

    public static AssetsSection Get() 
    { 
     return (AssetsSection) ConfigurationManager.GetSection("test/assets"); 
    } 

    protected override ConfigurationPropertyCollection Properties 
    { 
     get 
     { 
      return s_properties; 
     } 
    } 

    public String Path 
    { 
     get 
     { 
      return (String) base[s_propPath]; 
     } 
     set 
     { 
      base[s_propPath] = value; 
     } 
    } 
} 

class Program 
{ 
    static void Main(String[] args) 
    { 
     Console.WriteLine(AssetsSection.Get().Path); 

     Console.ReadLine(); 
    } 
} 
} 

Y el archivo App.config;

<?xml version="1.0"?> 
<configuration> 
<configSections> 
    <sectionGroup name="test"> 
     <section name="assets" type="ConsoleApplication1.AssetsSection, ConsoleApplication1"/> 
    </sectionGroup> 
</configSections> 

<startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/> 
</startup> 

<test> 
    <assets path="..\Assets"/> 
</test> 
</configuration> 
+0

¿Por qué compila para .NET 4.0 pero le obliga a ejecutar una versión anterior de la CLR? –

+0

Lo siento, pegué el archivo de configuración incorrecto de mi código de prueba. Edité la pregunta. Sin embargo, el problema sigue siendo, por supuesto. – David

Respuesta

17

intente cargar la configuración y abrir su primera sección en que:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
AssetsSection configSection = (AssetsSection)config.GetSection("test/assets"); 

me encontré con el mismo problema con .NET 4 y esto funciona para mí.

+0

Muchas gracias Timo. También funcionó para mí. Pero supongo que es un error. NET 4.0. – David

+1

Tenga en cuenta que mientras esto funciona en torno a la excepción, hay un problema de rendimiento: el xml deserializado NO se almacena en caché y ocurre cada vez que llama a OpenExeConfiguration(). La forma "correcta" (con errores) utilizando GetSection() almacena en caché la sección XML y lo reutilizará en llamadas posteriores. Esto puede o no afectar el rendimiento en su aplicación, dependiendo de cuán sensible sea el rendimiento y la frecuencia con que realiza llamadas a OpenExeConfiguration. – galaktor

-1

Estoy especulando aquí, pero sospecho que es su archivo de configuración que no es de confianza.

En su caso, su archivo de configuración hace referencia a un tipo ConsoleApplication1.AssetsSection que no tiene un nombre seguro que pueda utilizarse como evidencia.

Puede proporcionar más detalles y el mensaje de error exacto.

+0

Tengo el mismo problema, la configuración de mi aplicación se ve así y todavía tengo el problema

1

Si añade su propia clase para asignar la sección de la siguiente manera:

[XmlRoot("Interface")] 
public class MySectionClass 
{ 
    [XmlAttribute()] 
    public string MyAttr1 
    { 
     get; 
     set; 
    } 

    public string MyAttr2 
    { 
     get; 
     set; 
    } 
} 

Puede utilizar este código:

ConfigurationSection configSection = 
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None). 
GetSection("MySection"); 

XmlSerializer xs = new XmlSerializer(typeof(MySectionClass)); 

XmlDocument xdoc = new XmlDocument(); 
xdoc.LoadXml(configSection.SectionInformation.GetRawXml()); 

XmlNodeReader xnr = new XmlNodeReader(xdoc.DocumentElement); 

MySectionClass section = (MySectionClass)xs.Deserialize(xnr); 
4

Esto se debe a un error conocido en .NET 4.0 cuando se ejecuta la aplicación desde una red compartida.

El siguiente código falla con una SecurityException. Tenga en cuenta que sólo se produce un error cuando se ha definido un tipo personalizado para la sección como en este ejemplo AssetsSection:

ConfigurationManager.GetSection("test/assets"); 

Una solución es la sugerencia de solución de Timo utilizar un API diferente. Otra solución es aplicar el parche provisto por Microsoft.

El error y la revisión relacionada están archivados en KB2580188.

+0

La corrección funciona muy bien. –

Cuestiones relacionadas