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

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

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

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

安全异常

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

异常详细信息:System.Security.SecurityException:未找到源,但无法搜索部分或全部事件日志。不可访问的日志:安全性

源错误:

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

堆栈跟踪:

[SecurityException:未找到源,但无法搜索部分或全部事件日志。不可访问的日志:安全。]

System.Diagnostics.EventLog.FindSourceRegistration(String source,String machinename,Boolean readonly)+562 System.Diagnostics.EventLog.SourceExists(String Source,String MachineName)+251

[剪下]

以下是我尝试解决这个问题的方法:

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

  2. 我在应用程序日志和安全日志中创建了源代码(并通过注册表编辑器验证了它的存在),在安装过程中使用了提升的权限,但错误仍然存在。

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

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

PS:这是问题的后续。我按照给出的答案,但无济于事(见上面的#2)。

333845 次浏览

我没有在IIS上工作,但我确实有一个应用程序在2K8机器上抛出相同的错误。它在2K3盒子上工作得很好,去想想吧。

我的解决方案是“以管理员身份运行”,以提升应用程序的权限,一切都运行良好。我希望这能帮助你找到正确的方向。

Windows 2008的权限/权限/提升与Windows 2003确实不同,GAR.

解决方案是授予“网络服务”帐户对事件日志/安全密钥的读取权限。

对我来说,只有将“ NetworkService ”的“读取”权限授予整个“事件日志”分支才起作用。

要为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. 授予其读取权限

更新:上述步骤在开发人员计算机上是可以的,在这些计算机上您不使用部署过程来安装应用程序。
但是,如果您将应用程序部署到其他计算机,请考虑按照赛拉维的妮可·卡利诺尤的答案中的建议在安装过程中注册事件日志源

我正在使用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")
}
}
}

我遇到了类似的问题-在我的案例中,源代码包含<>字符。64位机器正在使用新的甚至日志XML基础,我想说的是,这些字符(从字符串中设置)创建无效的XML,这会导致异常。可以说,这应该被认为是微软的问题-没有正确处理源(名称/字符串)。

我也遇到了同样的问题,但我必须向上一层授予每个人对HKEY_本地_Machine\System\CurrentControlSet\Services\EventLog\Key的完全访问权限,而不是向下访问Security,这为我解决了问题。

Windows 7 64位

也存在同样的问题。 以管理员身份运行解决了该问题。

对我来说,这个异常发生在作为计划任务运行的.NET控制台应用程序中,我尝试做基本相同的事情-创建一个新的事件源并写入事件日志。

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

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

您好,我在开发应用程序时遇到了同样的问题,并希望将其安装在远程PC上,我通过执行以下操作解决了这个问题:

1)转到注册表,找到:HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application(您的_服务_或_应用程序_名称)

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

注2:根据您正在写入的事件日志,您可能会在您的开发框中找到\Application\(如上所述),或者(\System)或(\Security),这取决于您的应用程序正在写入的事件,大多数情况下,(\Application)应该始终正常。

2)在上面的键上,从菜单;选择“文件”->“导出”,然后保存文件。(注意:当应用程序需要访问此项以写入事件查看器时,这将创建必要的注册表设置),新文件将是一个.reg文件,为了便于讨论,将其命名为“我的新应用程序.reg ”

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

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

这个问题现在应该解决了。

原因:

在开发将任何内容写入EventLog的应用程序时,它需要在EventLog注册表下为其提供一个键。如果未找到此键,它将尝试创建它,然后由于没有权限而失败。上面的过程类似于部署应用程序(手动),而我们是自己创建的,不需要头痛,因为您不需要通过向每个人添加权限来调整注册表,这是生产服务器上的安全风险。

我希望这有助于解决它。

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

因此,我启动了一次我编译的程序作为管理员:它注册了事件源。 然后我回到VS内部进行开发和调试,没有任何问题。

(你也可以参考http://www.blackwasp.co.uk/eventlog_3.aspx,它帮助了我。

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

根据微软的建议,将其放回原处,纠正了这个问题。我怀疑让所有经过身份验证的用户在更高级别进行读取也会纠正您的问题。

重建解决方案对我很有效。

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

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

我在这里尝试了几乎所有的方法来解决这个问题……我在这里分享一下帮助我的答案:

解决问题的另一种方法:

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

凭据将被重新加载,并且可访问事件日志

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

仅供参考。我的问题是不小心选择了“本地服务”作为ProcessInstaller属性的帐户,而不是“本地系统”。我只是想提醒那些遵循MSDN教程的人,因为本地服务选择显示在第一位,而我没有密切关注……

问题是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\Application下找不到密钥,则下面的行将失败,因为EventLog.SourceExists将尝试访问EventLog\Security

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

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

HKEY_本地_计算机\System\CurrentControlSet\Services\EventLog\Application\DotNet示例应用程序

然后可以删除这两条线。

您还可以创建.reg文件来创建注册表项。只需将以下文本保存到ABC1__文件中:

Windows Registry Editor Version 5.00


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

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

我还在应用程序中添加了一个围绕log.source = "xx"的try/catch,以便在未创建事件源时将其设置为已知源(只有在热交换.DLL而不是重新安装时才会出现这种情况)。

解决方案非常简单-在管理模式下运行Visual Studio应用程序!

虽然安装程序的答案是一个很好的答案,但在处理您没有编写的软件时,它并不总是实用的。一个简单的答案是使用PowerShell命令新事件日志http://technet.microsoft.com/en-us/library/hh849768.aspx)创建日志和事件源。

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

new-eventlog-logname__abc0-source__abc1

我用它解决了CodePlex的聚合器运行时的事件日志异常问题。

使用System.Diagnostics.EventLog.WriteEntry(“ sourceName ”,“ errorMessage ”,EventLogEntryType.Error);时,需要在注册表编辑器中的HKEY_本地_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application下创建具有所用源名称的新项

因此,基本上您的用户没有创建密钥的权限。可以执行以下操作,具体取决于您通过应用程序池高级设置中的标识值使用的用户:

  1. 运行regedit并转到HKEY_本地_计算机\SYSTEM\CurrentControlSet\Services\EventLog
  2. 右键单击EventLog键,然后选择Permissions..选项 3.添加具有完全控制访问权限的用户。

    -如果您使用的是“网络服务”,请添加网络服务用户

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

    -如果使用“本地系统”,请确保用户具有管理员权限。不建议将其用于漏洞。

  3. HKEY_本地_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security重复步骤1到3

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

在下面的web.config中尝试

 <system.web>


<trust level="Full"/>


</system.web>

对于这个问题,似乎有一个显而易见的解决方案,但我还没有看到一个巨大的缺点,至少在为了创建自己的事件源而获得管理权限是不现实的:使用一个已经存在的事件源。

我已经开始使用的两个是“.NET运行时”和“应用程序错误”,这两个似乎都会出现在大多数机器上。

主要缺点是不能按事件进行分组,而且您可能没有关联的事件ID,这意味着日志条目很可能带有类似于“找不到源.NET运行时事件ID 0的描述.”的前缀(如果您省略了它),但日志仍然存在,而且输出看起来非常合理。

生成的代码如下所示:

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

当然,由于您所使用的计算机总有可能出于某种原因而没有这些事件源,因此您可能希望try {} catch{}包装它,以防它失败并使情况变得更糟,但事件现在是可保存的。

我有一个控制台应用程序,在那里我也做了一个“发布”。创建安装盘。
我在行动中也犯了同样的错误: Error Message

解决方案是右键单击setup.exe,然后单击Run as Administrator

这使安装过程具有必要的权限。