ConfigurationErrorsException / SecurityException / FileIOPermission在NLog实例化期间读取应用程序.config文件

时间:2013-12-06 10:13:23

标签: c# configuration .net-4.0 nlog securityexception

在尝试将NLog实例初始化为静态类成员时,我遇到了一个奇怪的异常(更新:这是在面向.NET 4.0的桌面应用程序中发生的)。

问题是,我只在一台特定的客户端计算机上获取它,并且无法在我的任何开发配置上重现。有人能指出我的方向,我应该寻找什么?

PS:用户也尝试使用管理员权限运行应用程序,获得相同的异常。

System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for nlog: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral,     PublicKeyToken=b77a5c561934e089" failed. (C:\Users\XXX\Desktop\Test.exe.Config line 9) ---> System.Security.SecurityException: Request for permission of type "System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" failed.
   in System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   in System.Security.CodeAccessPermission.Demand()
   in System.AppDomainSetup.VerifyDir(String dir, Boolean normalize)
   in NLog.Internal.Fakeables.AppDomainWrapper..ctor(AppDomain appDomain)
   in NLog.Internal.Fakeables.AppDomainWrapper.get_CurrentDomain()
   in NLog.Config.ConfigSectionHandler.System.Configuration.IConfigurationSectionHandler.Create(Object parent, Object configContext, XmlNode section)
   in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   in System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)
   --- End of inner exception stack trace ---
   in System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
   in System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   in System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   in System.Configuration.ConfigurationManager.GetSection(String sectionName)
   in NLog.Config.XmlLoggingConfiguration.get_AppConfig()
   in NLog.LogFactory.get_Configuration()
   in NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
   in NLog.LogFactory.GetLogger(String name)
   in NLog.LogManager.GetCurrentClassLogger()

更新(配置文件)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="Test.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
      <target name="logfile" xsi:type="File" fileName="log-${machinename}.txt" layout="${longdate} ${level:uppercase=True} ${logger} ${message} ${exception:format=ToString,StackTrace}" />
    </targets>
    <rules>
      <logger name="*" minlevel="Debug" writeTo="logfile" />
    </rules>
  </nlog>
    <applicationSettings>
    <Test.Properties.Settings>
        <setting name="servers" serializeAs="Xml">
            <value>
                <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <string>111</string>
                    <string>222</string>
                </ArrayOfString>
            </value>
        </setting>
    </Test.Properties.Settings>
    </applicationSettings>
</configuration>

NLog以这种方式实例化(类上的静态字段):

private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

2 个答案:

答案 0 :(得分:4)

解决方案是使用文件属性中的“取消阻止”按钮从应用程序.config文件中删除“不受信任的来源”标记,或Sysinternals Streams tool

感谢@giammin指出我正确的方向(信任级别)!

愚蠢的我。事实证明,问题的原因非常明显:这是Attachment Manager工作的结果。 “Untrusted origin”标志(Zone.Identifier备用数据流)在包含应用程序文件的下载存档上设置。

在这方面我意想不到的是:

  1. 我认为只有IE实施这种“保护措施”。事实证明,我错了 - 用户通过Chrome下载了该文件,Chrome也设置了这个标志。 Firefox没有设置它(我查看了迄今为止的最新版本)。
  2. 提取后将标志从存档(zip)复制到文件。我相信这发生了,因为用户使用内置的Windows归档工具提取文件。
  3. 此问题的直接原因不是程序集或可执行文件上的标志,而是.config文件本身的标志。一旦删除,问题就消失了。 .exe / .dll文件上的标志不会以任何方式解决问题。
  4. 我仍然不确定为什么这只会在.net 4.0上发生,并且在安装.net 4.5时会消失(应用程序文件完全相同)。

答案 1 :(得分:3)

要调试nlog,您可以使用其internal logging

<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">

--- --- UPDATE

另一项检查可能是将配置移动到外部文件:

<configSections>
    ...
  <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog configSource="NLog.config" />

NLog.config:

<?xml version="1.0"?>
<nlog autoReload="true" throwExceptions="true" internalLogFile="c:\log.txt" internalLogLevel="Trace">
...
</nlog>

无论如何,应用程序似乎没有在FullTrust中运行。

---- ---- UPDATE2

尝试在

中添加此requirePermission="false"
 <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" requirePermission="false"/>