Why does using ConfigurationManager.GetSection cause "SecurityException: Request failed" but ConfigurationManager.OpenExeConfiguration does not?

11,512

Solution 1

I had this same behavior when the assembly was "blocked" (under the file properties tab). The files were emailed via a zip to the admin. When he saved off the attachment, the block bit was added...just like when you download a file from the internet. After we clear the block, it worked fine.

Solution 2

ConfigurationManager.GetSection(String):

retrieves a configuration file obtained by merging the application configuration file, the local user configuration file, and the roaming configuration file.


ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel):

The userLevel parameter determines the location of the configuration file being opened by indicating whether it has no user level (the configuration file is in the same directory as the application)

So, they're opening different files. Take a look using ProcessMonitor to find out which files are being accessed and why an exception occurs and on which file.

Share:
11,512
kmp
Author by

kmp

SO Careers Profile: http://careers.stackoverflow.com/kevinphillips LinkedIn: http://www.linkedin.com/in/kevinphillips

Updated on July 18, 2022

Comments

  • kmp
    kmp almost 2 years

    I have something curious that I am hoping a .Net expert can help me with.

    I have a custom configuration section and to get hold of it I do this:

    var s = (TestConfigurationSection)ConfigurationManager
        .GetSection("testSection");
    

    I run that on my development machine (Windows 7, 64 bit, Windows completely up to date) and it works fine.

    I take the exe with that code in and I put it in a directory inside c:\users\public on a Windows Server 2008 R2 machine, open up a command prompt as administrator, run it and I get:

    System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for testSection: Request failed. (C:\Users\Public\configtest\AppConfigTestConsoleApplication.exe.Config line 10) ---> System.Security.SecurityException: Request failed.

    Now I changed that code to do this:

    var config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    var s = (TestConfigurationSection) config
        .GetSection("testSection");
    

    and it works fine on both machines.

    So, I am moderately happy (in as much as my application is working) but that little Gremlin in my head is confused so I ask here:

    Why is this the case?


    Steps to reproduce

    Create a new .net 4 Console application project called AppConfigTestConsoleApplication in visual studio 2010 and replace the contents of Program.cs with the following:

    using System;
    using System.Configuration;
    
    namespace AppConfigTestConsoleApplication
    {
        public class TestConfigurationSection : ConfigurationSection
        {
            [ConfigurationProperty("someSetting")]
            public int SomeSetting
            {
                get { return (int) this["someSetting"]; }
                set { this["someSetting"] = value; }
            }
        }
    
        internal class Program
        {
            private static void Main()
            {
                try
                {
                    var s = (TestConfigurationSection) ConfigurationManager
                        .GetSection("testSection");
                    Console.WriteLine("First Method worked: " + s.SomeSetting);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("First method failed");
                    Console.WriteLine(ex.ToString());
    
                    if (ex.InnerException != null)
                    {
                        var eex = ex.InnerException as SecurityException;
                        Console.WriteLine("Action: '{0}'", eex.Action.ToString());
                        Console.WriteLine("Demanded: '{0}'", eex.Demanded.ToString());
                        Console.WriteLine("RefusedSet: '{0}'", eex.RefusedSet);
                        Console.WriteLine("GrantedSet: '{0}'", eex.GrantedSet);
                    }
    
                    try
                    {
                        var config = ConfigurationManager.OpenExeConfiguration(
                            ConfigurationUserLevel.None);
    
                        var s = (TestConfigurationSection) config
                            .GetSection("testSection");
    
                        Console.WriteLine("Second Method worked: " 
                            + s.SomeSetting);
                    }
                    catch (Exception x)
                    {
                        Console.WriteLine("Even the second method failed!");
                        Console.WriteLine(ex.ToString());
                    }
                }
            }
        }
    }
    

    Then add an application configuration file and replace the contents with the following:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>  
        <section
          name="testSection"
          type="AppConfigTestConsoleApplication.TestConfigurationSection, AppConfigTestConsoleApplication"
          requirePermission="false"
          allowDefinition="Everywhere" />  
      </configSections>
      <testSection someSetting="10"></testSection>
    </configuration>
    

    Compile and run and this is the output I got:

    C:\Users\Public\configtest>AppConfigTestConsoleApplication.exe
    First method failed
    System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for testSection: Request failed. (C:\Users\Public\configtest\AppConfigTestConsoleApplication.exe.Config line 10) ---> System.Security.SecurityException: Request failed.
       at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
       at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
       at System.Configuration.TypeUtil.InvokeCtorWithReflectionPermission(ConstructorInfo ctor)
       at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
       at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
       at System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
       at System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)
       --- End of inner exception stack trace ---
       at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecordsectionRecord, Object parentResult)
       at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
       at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
       at System.Configuration.ConfigurationManager.GetSection(String sectionName)
       at AppConfigTestConsoleApplication.Program.Main()
    Action: 'Demand'
    Demanded: '<PermissionSet class="System.Security.PermissionSet"
    version="1"
    Unrestricted="true"/>
    '
    RefusedSet: ''
    GrantedSet: ''
    Second Method worked: 10
    

    Process Monitor

    I ran Process Monitor and set the filter like so:

    Process Monitor Filter

    And that left 508 events that are all one of:

    • NAME NOT FOUND
    • NO MORE ENTRIES
    • PATH NOT FOUND
    • FILE LOCKED WITH ONLY READERS
    • NO SUCH FILE (just once for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\93e7df09dacd5fef442cc22d28efec83\mscorlib.ni.dll and C:\Users\Public\configtest\AppConfigTestConsoleApplication.exe.config)
    • BUFFER OVERFLOW (for HKCU\Control Panel\Desktop\MuiCached\MachinePreferredUILanguages, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Cache,

    Does anyone have any advice perhaps on what filter to set to get to the root cause?

  • kmp
    kmp over 11 years
    Thanks for the answer - I ran process monitor but nothing jumped out at me (I am sure I am being dense) - can you recommend a filter perhaps?
  • kmp
    kmp over 11 years
    Great - thank you - that was it - when I looked at the file properties for my config file, on the General Tab in the security section it said the file may be blocked so I clicked "Unblock" and it then both methods worked fine.