写入事件日志时出现System.Security.SecurityException


189

我正在尝试将ASP.NET应用程序从Server 2003(和IIS6)移植到Server 2008(IIS7)。

当我尝试在浏览器上访问页面时,我得到以下信息:

“ /”应用程序中的服务器错误。

安全例外

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

异常详细信息:System.Security.SecurityException:找不到源,但是无法搜索某些或所有事件日志。无法访问的日志:安全性

源错误:

当前Web请求的执行期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来标识有关异常的来源和位置的信息。

堆栈跟踪:

[SecurityException:找不到源,但是无法搜索某些或所有事件日志。无法访问的日志:安全性。]

System.Diagnostics.EventLog.FindSourceRegistration(字符串源,字符串machineName,布尔型readOnly)+562 System.Diagnostics.EventLog.SourceExists(字符串源,字符串machineName)+251

[片段]

这些是我为尝试解决该问题所做的事情:

  1. 授予“所有人”对密钥的完全访问权限HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security。这工作了。但是自然地,我无法在生产中做到这一点。因此,在运行应用程序几分钟后,我删除了“所有人”权限,并且错误再次出现。

  2. 我在安装期间使用提升的权限在“应用程序”日志和“安全性”日志中创建了源(并通过regedit验证了它的存在),但错误仍然存​​在。

  3. 我在web.config文件中(并使用appcmd.exe)为该应用程序赋予了完全信任级别,但无济于事。

有没有人知道在这里可以做什么?

PS:这是此问题的后续措施。我遵循了给出的答案,但无济于事(请参阅上面的2)。


尝试写入以NetworkService运行的.Net服务中的自定义源时,出现了此错误。我只是更改了事件日志源,使其与通过.Net服务安装程序包设置的服务名称相匹配,并且无需设置注册表权限即可使用。我通过观察服务名称作为在HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\事件日志\应用程序已经在关键注意到了这一点
约翰·亚当斯


2
另一个可能的答案:右键单击exe,然后选择“以管理员
身份

Answers:


169

Network Service授予对EventLog/Security密钥的读取权限(如Firenzi和royrules22所建议),请按照http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx上的说明进行操作

  1. 打开注册表编辑器:
    1. Start然后选择Run
    2. 输入regedt32regedit
  2. 导航/扩展到以下键:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security

  3. 右键单击此条目,然后选择“权限”

  4. 添加Network Service用户

  5. 授予读取权限

更新:在不使用部署过程安装应用程序的开发人员机器上,上述步骤是可以的。
但是,如果将应用程序部署到其他计算机,请考虑按照SailAvidNicole Calinoiu的答案中的建议在安装过程中注册事件日志源

我正在使用PowerShell函数(在Octopus Deploy.ps1中调用)

function Create-EventSources() {
    $eventSources = @("MySource1","MySource2" )
    foreach ($source in $eventSources) {
            if ([System.Diagnostics.EventLog]::SourceExists($source) -eq $false) {
                [System.Diagnostics.EventLog]::CreateEventSource($source, "Application")
            }
    }
}

在IIS7中,您可以将“网络服务”分配为应用程序池的标识(您可能会发现ApplicationPoolIdentity是默认设置),或者可以在每个应用程序池中创建一个新用户并在该“自定义帐户”上设置权限。请参阅为应用程序池指定身份(IIS 7)
Grokodile 2013年

5
您重新启动aplication上IIS后的变化只需要影响
泽·卡洛斯·

7
我授予IIS_IUSRS权限,以读取/写入事件日志密钥,并读取安全密钥。我的产品需要对事件日志键进行写访问,因为它创建了自己的事件源。
duck9 2013年

1
duck9我纠正IIS8,在这里看到更多的细节:stackoverflow.com/questions/712203/...
thedrs

1
另请参阅关于应用程序池用户和相关权限的serverfault.com/a/81246/219898-此解决方案。谢谢@Michael Freidgeim-是很大的帮助。
安东尼·霍恩

58

问题是EventLog.SourceExists尝试访问EventLog\Security密钥,只有管理员才能访问。

C#程序登录的常见示例EventLog是:

string sSource;
string sLog;
string sEvent;

sSource = "dotNET Sample App";
sLog = "Application";
sEvent = "Sample Event";

if (!EventLog.SourceExists(sSource))
    EventLog.CreateEventSource(sSource, sLog);

EventLog.WriteEntry(sSource, sEvent);
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234);

但是,如果该程序没有管理员权限并且在下找不到密钥,则以下行将失败EventLog\ApplicationEventLog.SourceExists然后尝试访问EventLog\Security

if (!EventLog.SourceExists(sSource))
    EventLog.CreateEventSource(sSource, sLog);

因此,推荐的方法是创建一个安装脚本,该脚本创建相应的密钥,即:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \ Application \ dotNET示例应用程序

然后可以删除这两行。

您也可以创建一个.reg文件来创建注册表项。只需将以下文本保存到文件中create.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App]

1
这正是我为所有服务所做的。我相信这是正确的做法。在使用事件日志的每项服务中,都有一个与上述文件类似的.reg文件。一点点注意,该文件必须另存为Unicode-32(cp1200。)
Valo 2015年

此答案描述了错误背后的真正原因。存在的检查尝试枚举整个密钥。如果存在,则checkExists可以正常工作。
DanO

EventLog \ Security这是起作用的关键,请确保您对此具有权限。
普林卡

45

解决方案是授予“网络服务”帐户对EventLog / Security密钥的读取权限。


1
我看到类似的解决方案。但是我只是想知道为什么会这样。因为我可以看到很多服务都以NetworkService身份登录,所以它们必须能够读取事件日志/安全性。那么,为什么需要为NetworkService添加权限?
h--n

11
对于通常不通过注册表进行爬网的我们来说,此链接可能会有所帮助:social.msdn.microsoft.com/forums/en-US/…–
Allan

尼斯链接艾伦。公认答案的第3点很重要,并且已经咬过我一次。即,在父EventLog注册表项上授予权限不会传播到“不可访问的日志”,例如Security和Virtual Server,即使它们是注册表中的子项。如果要获得完整的事件日志访问权限,则必须同时在父事件日志级别和子安全级别上授予权限。
Ben Barreth 2012年

1
您重新启动aplication上IIS后的变化只需要影响
泽·卡洛斯·

对于那些尝试复制/粘贴的用户,请确保在“网络服务”一词之间留有空格。
克里斯·弗雷姆根

7

对我来说,仅向整个“ EventLog”分支授予“ NetworkService”的“读取”权限就可以


这不是很相关,因为对于“安全”或“虚拟服务器”之类的子项,需要单独授予读取访问权限,因为权限已设置为不继承自父项。
Serge 2014年

7

我在VS2010下开发的控制台程序(从XP下的VS2008升级)有一个非常类似的问题,我的编使用EnLib进行了一些日志记录。由于EntLib没有注册新事件源的权限而引发了错误。

因此,一旦我编译的编以管理员身份开始,便开始:它注册了事件源。然后,我从VS内部回去进行开发和调试,没有问题。

(您也可以参考http://www.blackwasp.co.uk/EventLog_3.aspx,它对我有帮助


7

我是通过按计划任务运行的.NET控制台应用程序发生此异常的,而我试图做的基本上是同一件事-创建一个新的事件源并写入事件日志。

最后,为在以下按键上运行任务的用户设置完全权限对我有用:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog

3
你救了我的日子。顺便说一句,在eventlog\Application和上具有阅读权限就足够了eventlog\Securityeventlog仅在根目录上需要完全控制。
Ruud Helderman 2014年

6

我在这里尝试了几乎所有方法来解决此问题...在这里分享对我有帮助的答案:

解决问题的另一种方法:

  • 在IIS控制台中,转到管理站点的应用程序池,并记下运行它的身份(通常是网络服务)
  • 确保此身份可以读取KEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Eventlog(单击鼠标右键,授权)
  • 现在,将此应用程序池的标识更改为“本地系统”,应用并切换回“网络服务”

凭证将被重新加载并且EventLog可访问

http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx中,感谢Michael Freidgeim


将应用程序池从“ ApplicationPoolIdentity”更改为“ LocalSystem”解决了为我创建/读取事件日志的问题。
majestzim

4

我遇到了同样的问题,但是我必须上一层楼,并向所有人授予对HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \密钥的完全访问权限,而不是为了安全,这为我解决了这个问题。


1
另外,请尝试将应用程序设置为以LocalSystem身份运行,以便创建注册表项,然后您可以随后更改回NetworkService。
demoncodemonkey

4

在Windows 7 64bits上也存在同样的问题。以管理员身份运行即可解决问题。


4

使用System.Diagnostics.EventLog.WriteEntry(“ SourceName”,“ ErrorMessage”,EventLogEntryType.Error)时,需要在regEdit中的HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Application下创建使用源名称的新密钥

因此,基本上,您的用户无权创建密钥。根据“应用程序池高级”设置中的“标识”值,您可以根据所使用的用户执行以下操作:

  1. 运行RegEdit并转到HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog
  2. 右键单击EventLog项,然后选择Permissions ...选项。3.添加具有完全控制访问权限的用户。

    -如果您使用的是“ NetworkService”,则添加NETWORK SERVICE用户

    -如果您使用的是“ ApplicationPoolIdentity”,请添加IIS APPPOL {您的应用程序池名称}(搜索用户时使用本地计算机位置)。

    -如果您使用的是“ LocalSystem”,请确保用户具有管理员权限。不建议使用此漏洞。

  3. HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Security重复从1到3的步骤

对于使用Visual Studio进行调试,我使用“ NetworkService”(它是ASP.NET用户),发布网站时,我使用“ AppicationPoolIdentity”。


3

仅供参考...我的问题是不小心选择了“本地服务”作为ProcessInstaller属性的帐户,而不是“本地系统”。刚刚提到的是跟随MSDN教程的其他人,因为“本地服务”选择首先显示出来,而我并没有密切注意...。


3

确实有一个显而易见的解决方案,我还没有看到很大的缺点,至少在为了创建自己的事件源而无法获得管理权限的地方:请使用已经存在的事件源。

我开始使用的两个是“ .Net Runtime”和“ Application Error”,它们似乎都将出现在大多数计算机上。

主要缺点是无法按该事件分组,并且您可能没有关联的事件ID,这意味着该日志条目可能带有一些前缀,以达到“来自源.Net的事件ID 0的描述”的作用。如果找不到运行时,将无法找到运行时。...”,但是日志进入了,并且输出看起来很合理。

结果代码最终看起来像:

EventLog.WriteEntry(
    ".Net Runtime", 
    "Some message text here, maybe an exception you want to log",
    EventLogEntryType.Error
    );

当然,由于出于某种原因,您总是有机会处于没有这些事件源的机器上,因此您可能希望将其try {} catch{}包装起来,以防万一它失败并使情况变得更糟,但是现在可以保存事件了。


2

我不在IIS上工作,但确实有一个在2K8盒子上引发相同错误的应用程序。它可以在2K3盒子上正常工作。

我的解决方案是“以管理员身份运行”以赋予应用程序更高的权限,并且一切都愉快地进行。希望这有助于您朝正确的方向发展。

Windows 2008的权限/许可/权限确实与Windows 2003 gar不同。


2

嗨,我在开发应用程序并将其安装在远程PC上时遇到了同样的问题,我通过执行以下操作来修复它:

1)转到注册表,找到:HKLM \ System \ CurrentControlSet \ Services \ EventLog \ Application(??? YOUR_SERVICE_OR_APP_NAME ???)

请注意,“(??? YOUR_SERVICE_OR_APP_NAME ???)”是您在创建.NET部署时定义的应用程序服务名称,例如,如果您将新应用程序命名为“ My new App”,则密钥为: HKLM \ System \ CurrentControlSet \ Services \ EventLog \ Application \ My New应用程序

注意2:根据要写入的事件日志,您可能会在DEV框上找到\ Application \(如上所述),或者也可能是(\ System)或(\ Security),这取决于应用程序要写入的事件,主要是,(\ Application)应该一直都很好。

2)在上面的键上,从菜单中;选择“文件”->“导出”,然后保存文件。(注意:当应用程序需要访问此注册表项以将其写入事件查看器时,这将创建您必要的注册表设置),新文件将是.REG文件,出于参数的缘故,将其称为“我的新App.REG” ”

3)在PRODuction上进行部署时,请咨询服务器系统的管理员(SA),将“ My New App.REG”文件与应用程序一起移交,并要求SA安装此REG文件,完成后(作为管理员)为您的应用创建密钥。

4)运行您的应用程序,除了此键外,它不需要访问其他任何内容。

现在应该解决问题。

原因:

在开发将任何内容写入EventLog的应用程序时,如果找不到该密钥,则需要在Eventlog注册表下为其输入KEY,它将尝试创建它,然后由于没有权限这样做而失败。上面的过程类似于(手动)部署应用程序,而我们是自己创建的,因此无需麻烦,因为您无需通过向EVERYONE添加权限来调整注册表,这在生产服务器上存在安全风险。

我希望这有助于解决它。


2

尽管安装程序的答案是一个很好的答案,但是在处理您未编写的软件时,它并不总是实用的。一个简单的答案是使用PowerShell命令New-EventLoghttp://technet.microsoft.com/zh-cn/library/hh849768.aspx)创建日志和事件源。

以管理员身份运行PowerShell,然后运行以下命令以更改所需的日志名称和源。

New-EventLog -LogName 应用程序-TFSAggregator

我用它来解决Aggregator从Codeplex 运行问题时发生事件日志异常


1

我们所有的2008服务器都出现了类似的问题。由于GPO占用了组Authenticated Users并从密钥中读取了权限,因此安全日志完全停止工作HKLM\System\CurrentControlSet\Services\EventLog\security

按照Microsoft的建议放回此位置,可以解决此问题。我怀疑允许所有经过身份验证的用户更高级别地阅读也可以解决您的问题。


1

我打了类似的问题-在我的情况源包含<>字符。我会说64位计算机正在使用新的偶数日志-xml基础,并且这些字符(从字符串设置)会创建无效的xml,从而导致异常。可以说这应该是Microsoft的问题-无法正确处理源(名称/字符串)。


1

解决方案非常简单-以Admin模式运行Visual Studio应用程序!


在VS中进行故障排除并得到此错误后,这确实为我解决了
wruckie 2015年

这可能会出错,因为调用此调用的不是VS,而是可能在不同安全性上下文下运行的应用程序。
CodeMonkey1313

0

我的应用程序已安装在客户端Web服务器上。我没有摆弄网络服务权限和注册表,而是选择在安装程序中检查SourceExists并运行CreateEventSource

log.source = "xx"如果未创建事件源,我还在应用程序中添加了一个try / catch 来将其设置为已知源(仅当我热交换.dll而不是重新安装时才会出现)。



-1

在VS中运行应用程序时遇到了这个问题。我所要做的只是以管理员身份运行该程序一次,然后可以在VS中运行。

要以管理员身份运行,只需在Windows资源管理器中导航到调试文件夹。右键单击该程序,然后选择“以管理员身份运行”。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.