为什么使用ConfigurationManager.GetSection会导致“SecurityException:Request failed”,但ConfigurationManager.OpenExeConfiguration却没有?

时间:2012-11-23 12:08:15

标签: c# .net .net-4.0

我有一些好奇,我希望.Net专家可以帮助我。

我有一个自定义配置部分,为了掌握它,我这样做:

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

我在我的开发机器上运行它(Windows 7,64位,Windows完全是最新的)并且它运行正常。

我将exe代码加入,并将其放在c:\users\public机器上的Windows Server 2008 R2内的目录中,以管理员身份打开命令提示符,运行它然后我得到:

  

System.Configuration.ConfigurationErrorsException:为testSection创建配置节处理程序时发生错误:请求失败。 (C:\ Users \ Public \ configtest \ AppConfigTestConsoleApplication.exe.Config第10行)---> System.Security.SecurityException:请求失败。

现在我更改了代码来执行此操作:

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

它在两台机器上都能正常工作。

所以,我感到中等开心(尽管我的申请工作正常)但是我头脑中的那个小Gremlin很困惑所以我在这里问:

为什么会这样?


重现的步骤

在visual studio 2010中创建一个名为AppConfigTestConsoleApplication的新.net 4控制台应用程序项目,并将Program.cs的内容替换为以下内容:

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

然后添加应用程序配置文件并使用以下内容替换内容:

<?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>

编译并运行,这是我得到的输出:

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并设置过滤器,如下所示:

Process Monitor Filter

这留下了508个事件,它们都是:

  • NAME NOT FOUND
  • 没有更多条目
  • 未找到路径
  • 仅与读者联系的文件
  • 没有这样的文件(只有一次用于 C:\ Windows \ assembly \ NativeImages_v4.0.30319_32 \ mscorlib \ 93e7df09dacd5fef442cc22d28efec83 \ mscorlib.ni.dll C:\ Users \ Public \ configtest \ AppConfigTestConsoleApplication.exe.config
  • BUFFER OVERFLOW(适用于 HKCU \ Control Panel \ Desktop \ MuiCached \ MachinePreferredUILanguages HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ User Shell Folders \ Cache

是否有人对可以设置哪些过滤器以获得根本原因有任何建议?

3 个答案:

答案 0 :(得分:10)

当程序集被“阻止”时(在文件属性选项卡下),我有同样的行为。这些文件通过zip通过电子邮件发送给管理员。当他保存了附件时,块位被添加......就像从互联网上下载文件一样。清除块后,它工作正常。

答案 1 :(得分:6)

  

ConfigurationManager.GetSection(String)

     

检索通过合并应用程序配置文件,本地用户配置文件和漫游配置文件获得的配置文件。


  

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel)

     

userLevel参数通过指示是否没有用户级别(配置文件与应用程序位于同一目录中)来确定要打开的配置文件的位置

所以,他们正在打开不同的文件。查看使用ProcessMonitor查看正在访问的文件以及发生异常的原因以及文件。

答案 2 :(得分:0)

我知道这是一个旧帖子,但我最近在与客户合作时遇到了这个问题,并且认为我发布了另一个建议。在我的情况下,问题是使用非静态ConfigurationManager方法,该方法可能在某些特定条件下导致SecurityException(应用程序以.NET Framework 4为目标并安装在网络驱动器上,在这种情况下也禁用Windows Update)。以下是有关该问题的更多信息以及Microsoft的修补程序:

https://support.microsoft.com/en-us/help/2580188/fix-system.security.securityexception-occurs-when-a-.net-framework-4-based-application-that-calls-a-static-method-in-the-system.configuration.configurationmanager-class-runs-on-a-network-share