使用非管理员帐户的log4Net eventlog权限问题

时间:2011-12-09 15:45:13

标签: iis-7 log4net event-log

这可能不是SiteCore本身的问题,但我已将其包含在内以保证完整性。我使用应用程序池的自定义标识在IIS7下运行sitecore 6.3。我无法让Sitecore将其日志信息(使用默认的log4net设置)写入事件日志。我遵循了这里的建议:http://logging.apache.org/log4net/release/faq.html#Why%20doesn%27t%20the%20EventLogAppender%20work?虽然当我将自定义标识作为管理员组的成员时它可以正常工作,但我需要找到一种方法让它在没有安全黑客的情况下在生产中工作。

奇怪的是我有一个安装它的MSI(在管理员组成员的帐户下运行)并在事件日志中为我创建了正确的注册表项,尽管如此,我仍然得到了使用自定义标识运行应用程序时出现以下错误(没有它是管理员的成员)。

log4net:ERROR DOMConfigurator: Could not create Appender [EventLogAppender] of type [log4net.Appender.EventLogAppender]. Reported error follows.
System.Security.SecurityException: Requested registry access is not allowed.
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at System.Diagnostics.EventLog.GetEventLogRegKey(String machine, Boolean writable)
at System.Diagnostics.EventLog.FindSourceRegistration(String source, String machineName, Boolean readOnly)
at System.Diagnostics.EventLog.DeleteEventSource(String source, String machineName)
at log4net.Appender.EventLogAppender.ActivateOptions()
at log4net.Repository.Hierarchy.DOMHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
The Zone of the assembly that failed was:
MyComputer
log4net:ERROR DOMConfigurator: Appender named [EventLogAppender] not found.

认为我可以将其缩小到注册表权限问题我已授予Everyone对以下注册表项和子项的完全权限,但它也不起作用:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog

自定义标识是以下组的成员:

  • 事件日志读者
  • IIS_USERS
  • 性能监视器用户

我也看到following question似乎问了同样的事情。微软的文章似乎暗示它可能是事件日志中ACL的问题,并提供了如何更改SSDL的示例,但我宁愿尽可能避免这种情况。

编辑: 我有另一台服务器正在运行,其中日志正在填充正常。自定义标识是管理员的成员所以我撤销了它并重新启动,试图故意破坏它,但我不能。两个框上的配置相同,并且用于运行MSI的相同标识创建了注册表项。在两者上运行procmon(在执行IISReset并再次启动应用程序池之后)以检查注册表活动。奇怪的是 - 在可行的方框中,您在错误的位置(应用程序和不同的自定义事件日志“MyCompany”)获取477名称未找到的事件源记录。没有命中它记录的地方是“MyCompany \ MyCompany.SiteCore”。虽然在破坏的盒子上,它似乎确实要求读取正确的密钥(尽管只有6次)但是你得到了Log4Net注册表访问错误。

2 个答案:

答案 0 :(得分:4)

据我所知,EventStores存储在注册表中,因此您只需要注册表的写权限即可创建或删除EventStore。这通常只需要一次,并且大多数应用程序在安装过程中创建它,以便在正常执行期间不需要以管理员身份运行应用程序。

然而,您的错误消息(在问题中)包含方法 DeleteEventSource ,我将从中推断/猜测EventSource确实存在但在某种程度上是错误的。因此,这可能是当前注册为写入名为MyCompany的事件日志,您现在正尝试将其更改为“MyCompany \ MyCompany.SiteCore”,这需要您删除旧的eventsource并创建一个新的事件源。

因此,听起来您的安装例程正在创建与您的应用程序实际使用的EventSource不同的EventSource。

如果这没有帮助,那么我建议启用internal logging for Log4net(但显然不是事件日志),这可能会为您提供更多信息。

授予注册表项的完全权限是不够的。 根据{{​​3}}

  

要在Windows Vista及更高版本或Windows Server 2003中创建事件源,您必须具有管理权限。

     

此要求的原因是必须搜索所有事件日志(包括安全性)以确定事件源是否唯一。从Windows Vista开始,用户无权访问安全日志;因此,抛出SecurityException。

     

从Windows Vista开始,用户帐户控制(UAC)确定用户的权限。如果您是内置管理员组的成员,则会为您分配两个运行时访问令牌:标准用户访问令牌和管理员访问令牌。默认情况下,您处于标准用户角色。要执行访问安全日志的代码,必须首先将您的权限从标准用户提升为管理员。您可以通过右键单击应用程序图标并指示要以管理员身份运行来启动应用程序时执行此操作。

答案 1 :(得分:2)

我认为,与Apache documentation相反,log4net需要对注册表进行写访问 - 或者至少在我的情况下是这样。为了证明这一点,我在服务器上备份了注册表,并且在启动sitecore之前授予了IIS管理员权限。果然它开始很好地记录到事件日志然后当我再次导出注册表来运行差异时,就会有差异。

我的事件源上的eventlogmessage文件的值已从以下更新:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\EventLogMessages.dll

所以我假设只是手动更改注册表中的这个值就行了。

但事实并非如此。

所以我在我拥有的两台服务器上运行procmon:A =工作的,B =失败的服务器。果然,在服务器B上我有一条线说: 的 Operation: RegOpenKey, Path: HKLM\System\CurrentControlSet\Services\EventLog, Desired Access:Read/Write, Result: ACCESS DENIED.

我已经跟踪了服务器A并且在完全相同的位置,使用Desired Access:Read请求密钥。

<强>结论: 似乎不可避免的是,我需要在生产中授予我的应用程序池身份管理员权限至少足够的时间以编程方式从log4net中第一次执行必要的注册表写入。我不知道为什么管理员;我已经尝试向我的自定义应用程序注册表中的整个事件日志节点授予完全权限,但无济于事。它似乎做了一些我无法识别或确定的东西。然后,我会在它开始记录后立即撤销此权限,并监控后续安装是否会破坏后续功能。 (希望不是)。

如果有人对此行为有任何了解,我们将不胜感激。