C#WebApp log4net部分信任(高或中)无法正常工作

时间:2012-03-14 11:00:19

标签: c# security log4net code-access-security

我在VS2010中创建了一个简单的.NET 4 Web应用程序,并添加了对log4net 1.2.11.0(最新)的引用。

在这个项目中,我做了一个Logger课程(见本文末尾)。当我在完全信任环境中调用此Logger类(Logger.Fatal("Test");)时,一切正常。但是,当我将信任级别更改为高(或中)时,它会失败并出现以下异常:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeLoadException: Inheritance security rules violated while overriding member: 'log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
   at log4net.Repository.Hierarchy.Hierarchy..ctor(ILoggerFactory loggerFactory)
   at log4net.Repository.Hierarchy.Hierarchy..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(String repositoryName, Type repositoryType)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType, String repositoryName, Boolean readAssemblyAttributes)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType)
   at log4net.Core.DefaultRepositorySelector.GetRepository(Assembly repositoryAssembly)
   at log4net.Core.LoggerManager.GetRepository(Assembly repositoryAssembly)
   at log4net.Config.XmlConfigurator.Configure()
   at UtilClasses.Logger..cctor() in c:\users\***\documents\visual studio 2010\Projects\TestLogging\TestLogging\Default.aspx.cs:line 35

log4net.Config.XmlConfigurator.Configure();抛出此异常。所以看起来我的应用程序甚至无法读取我的web.config

我发现在requestPermissions="false"标记中添加<section>会有所帮助,但是,现在我根本无法启动我的应用程序。

你们有什么线索如何解决这个问题吗?

记录器类

public static class Logger
{
    private static readonly log4net.ILog log;

    static Logger()
    {
        try {
            log4net.Config.XmlConfigurator.Configure();
            log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.Write(e.ToString());
        }
    }

    public static void LogInfo(string information)
    {
        log.Info(information);
    }

    public static void LogError(string erroMessage, Exception ex)
    {
        log.Error(erroMessage, ex);
    }

    public static void LogWarnings(string warningText)
    {
        log.Warn(warningText);
    }

    public static void Fatal(string fatalText)
    {
        log.Fatal(fatalText);
    }
}

配置文件(web.config):

<?xml version="1.0"?>

<configuration>

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <trust level="High" />
  </system.web>
  <log4net debug="true">
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="log\logfile.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <datePattern value="yyyy-MM-dd" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{dd-MM-yyyy HH:mm:ss,fff} [%-2p] - %C.%M - %m%n" />
      </layout>

    </appender>

    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>
  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

完整的调试器输出(没有w3wp信息):

'w3wp.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll'
log4net: log4net assembly [log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a]. Loaded from [C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\testlogging\57d742cb\fe23fd98\assembly\dl3\5a80c88f\005a56f5_5784cc01\log4net.DLL]. (.NET Runtime [4.0.30319.261] on Microsoft Windows NT 6.1.7601 Service Pack 1)
log4net: defaultRepositoryType [log4net.Repository.Hierarchy.Hierarchy]
log4net: Creating repository for assembly [TestLogging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
log4net: Assembly [TestLogging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] Loaded From [C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\testlogging\57d742cb\fe23fd98\assembly\dl3\a4f1c9bb\cc1c77d4_ce01cd01\TestLogging.DLL]
log4net: Assembly [TestLogging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] does not have a RepositoryAttribute specified.
log4net: Assembly [TestLogging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy]
log4net: Creating repository [log4net-default-repository] using type [log4net.Repository.Hierarchy.Hierarchy]
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeLoadException: Inheritance security rules violated while overriding member: 'log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
   at log4net.Repository.Hierarchy.Hierarchy..ctor(ILoggerFactory loggerFactory)
   at log4net.Repository.Hierarchy.Hierarchy..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(String repositoryName, Type repositoryType)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType, String repositoryName, Boolean readAssemblyAttributes)
   at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType)
   at log4net.Core.DefaultRepositorySelector.GetRepository(Assembly repositoryAssembly)
   at log4net.Core.LoggerManager.GetRepository(Assembly repositoryAssembly)
   at log4net.Config.XmlConfigurator.Configure()
   at UtilClasses.Logger..cctor() in c:\users\***\documents\visual studio 2010\Projects\TestLogging\TestLogging\Default.aspx.cs:line 35

[编辑] 我包含了log4net源而不是DLL,并且发现当log4net创建存储库的新实例时,异常会被删除。 这是DefaultRepositorySelector.cs,(第424-426行):

                        // Call the no arg constructor for the repositoryType
                        var x = Activator.CreateInstance(repositoryType);
                        rep = (ILoggerRepository)x;

3 个答案:

答案 0 :(得分:9)

事实证明我必须自己修改log4net的来源。

首先,源版本中log4net的构建配置文件不正确。我们必须添加NET4定义器。 同样在Assemblyinfo.cs中,必须在规则40中添加以下属性[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]

旧代码:

#if (!NETCF)
//
// If log4net is strongly named it still allows partially trusted callers
//
[assembly: System.Security.AllowPartiallyTrustedCallers]
#endif

新代码:

#if (!NETCF)
//
// If log4net is strongly named it still allows partially trusted callers
//
[assembly: System.Security.AllowPartiallyTrustedCallers]
[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]
#endif

现在在发布模式下编译后,我没有任何问题。

答案 1 :(得分:2)

我发现this blog post描述了如何解决您的问题。

这些是使Log4Net以中等信任方式工作所需的更改。

  1. 在configSections部分添加了log4Net部分声明 web.config并确保设置了requirePermission属性 价值为假。
  2. 将log4Net设置移至web.config。
  3. 从AssemblyInfo.cs
  4. 中删除了程序集属性XmlConfigurator
  5. 添加了对XmlConfigurator.Configure()的调用 Global.asax.cs中的Application_Start方法。

答案 2 :(得分:2)

上述申请后,又出现了另一个错误:

安全例外 说明:应用程序尝试执行安全策略不允许的操作。要授予此应用程序所需的权限,请与系统管理员联系或在配置文件中更改应用程序的信任级别。

异常详细信息:System.Security.SecurityException:请求类型为'System.Security.Permissions.ReflectionPermission,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'的权限失败。

通过添加

解决了上述问题
<system.web>
    <trust level="Full" />
</system.web>