Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# WebApp log4net partial trust (High or Medium) not working

I've made a simple .NET 4 Web Application in VS2010, and added a reference to log4net 1.2.11.0 (latest).

In this project I've made a Logger class (see end of this post). When I call this Logger class (Logger.Fatal("Test");) in a Full trust environment, everything works correct. However, when I change the trust level to High (or Medium) it fails with the following exception:

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

This exception is thrown at log4net.Config.XmlConfigurator.Configure();. So it looks my application can't even read my web.config

I found adding requestPermissions="false" to the <section> tag should help, however, now I can't start my application at all.

Do you guys have any clue how to fix this?

Logger class:

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

Config file (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>

The complete debugger output (without the w3wp info):

'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

[Edit] I included the log4net source instead of the DLL, and found out the exception is trown when log4net creates a new instance of the repository. This is in the DefaultRepositorySelector.cs, (row 424-426):

                        // Call the no arg constructor for the repositoryType
                        var x = Activator.CreateInstance(repositoryType);
                        rep = (ILoggerRepository)x;
like image 378
Michiel van Vaardegem Avatar asked Mar 14 '12 11:03

Michiel van Vaardegem


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

What is C full form?

Full form of C is “COMPILE”. One thing which was missing in C language was further added to C++ that is 'the concept of CLASSES'.


2 Answers

It turned out I had to modify the source for log4net myself.

First of all, the build profile of log4net wasn't correct in the source version. We had to add the NET4 definer to it. Also in the Assemblyinfo.cs, the following attribute [assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)] had to be added at rule 40.

Old code:

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

New code:

#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

After compiling now in release mode, I don't have any problems.

like image 114
Michiel van Vaardegem Avatar answered Sep 28 '22 19:09

Michiel van Vaardegem


I have found this blog post that describe how to resolve your problem.

These are the changes required to get Log4Net to work in medium trust.

  1. Added the log4Net section declaration in the configSections section of web.config and made sure the requirePermission attribute is set to the value false.
  2. Moved the log4Net settings into web.config.
  3. Removed the assembly attribute XmlConfigurator from AssemblyInfo.cs
  4. Added the call to XmlConfigurator.Configure() to the Application_Start method in Global.asax.cs.
like image 22
Steve Avatar answered Sep 28 '22 19:09

Steve