Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET 4.0 application on network share causes SecurityException

Today I experienced a weird problem while trying to remotely debug an application built for the .NET 4.0 runtime.

The application resides on a network share and executed by a remote machine. However the application crashes each time during load because of a SecurityException raised by a permission demand in the System.Configuration.ConfigurationManager.GetSection() method. I have not checked if other permission demands in the base class library also cause a security exception but in all cases this shouldn't be happening with the new CLR.

The application is running in full trust (checked it while debugging and as usual this must be always true for intranet applications in CLR 4.0) so I am clueless how a permission demand can cause an exception in this case. When built against the 3.5 SP1 runtime (which first introduced full trust for network shared apps by default) everythings runs as expected.

I pasted the sample code below. Any help is greatly appreciated.

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

And the App.config file;

<?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>
like image 854
David Avatar asked Apr 27 '10 21:04

David


3 Answers

Try loading the configuration first and open your section on that:

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

I ran into the same issue with .NET 4 and this works for me.

like image 129
Timo Kuper Avatar answered Oct 07 '22 05:10

Timo Kuper


This is due to a known bug in .NET 4.0 when running the application from a network share.

The follow code fails with a SecurityException. Note that it only fails when you have defined a custom type for the section like in this example AssetsSection:

ConfigurationManager.GetSection("test/assets");

One fix is the solution suggestion by Timo to use a different API. Another solution is to apply the patch provided by Microsoft.

The bug and the related hotfix is filed under KB2580188.

like image 28
Bhavesh Avatar answered Oct 07 '22 06:10

Bhavesh


If you add your own class to map the section like this:

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

    public string MyAttr2
    {
        get;
        set;
    }
}

You can use this code:

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);
like image 29
Jenzo Avatar answered Oct 07 '22 06:10

Jenzo