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

问题描述 投票:180回答:22

我正在努力尝试将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的完全访问权限。这很有效。但我自然不能在生产中这样做。所以我在运行应用程序几分钟后删除了“Everyone”权限,错误重新出现。
  2. 我在应用程序日志和安全日志中创建了源代码(我通过regedit对其进行了验证)在安装期间使用提升的权限,但错误仍然存​​在。
  3. 我给了应用程序在web.config文件中的完全信任级别(并使用appcmd.exe),但无济于事。

有没有人能够了解这里可以做些什么?

PS:这是对这个question的跟进。我按照给出的答案但没有用(见上面的#2)。

asp.net windows iis-7 exception-handling event-log
22个回答
166
投票

要给Network Service读取EventLog/Security密钥的许可(按照Firenzi和royrules22的建议),请遵循http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx的说明

  1. 打开注册表编辑器: 选择Start然后Run 输入regedt32regedit
  2. 导航/展开到以下键: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security
  3. 右键单击此条目并选择权限
  4. 添加Network Service用户
  5. 给它读取权限

更新:上述步骤适用于开发人员计算机,您不使用部署过程来安装应用程序。 但是,如果将应用程序部署到其他计算机,请考虑按照SailAvid'sNicole Calinoiu's答案中的建议在安装期间注册事件日志源。

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

3
投票

仅供参考...我的问题是,意外地选择“本地服务”作为ProcessInstaller属性的帐户而不是“本地系统”。只是提到任何跟随MSDN教程的人,因为本地服务选择首先显示,我没有密切关注....


3
投票

当您使用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键并选择权限...选项3.添加具有完全控制访问权限的用户。 - 如果您使用“NetworkService”添加NETWORK SERVICE用户 - 如果您是usinf“ApplicationPoolIdentity”,请添加IIS APPPOL {您的应用程序池的名称}(在搜索用户时使用本地计算机位置)。 - 如果您使用“LocalSystem”,请确保该用户具有管理员权限。不建议使用漏洞。
  3. 为HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Security重复步骤1到3

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


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部署时定义的应用程序服务名称,例如,如果您将新应用程序命名为“我的新应用程序”,则密钥将为: HKLM \ System \ CurrentControlSet \ Services \ EventLog \ Application \ My New app

注意2:根据您写入的eventLog,您可以在DEV框中找到\ Application \(如上所述),或者(\ System)或(\ Security),具体取决于您的应用程序写入的内容,主要是,(\ Application)应该一直都很好。

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

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

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

问题现在应该解决了。

原因:

当开发一个将任何东西写入EventLog的应用程序时,如果找不到这个密钥,它将在Eventlog注册表中需要一个KEY,它会尝试创建它,然后由于没有权限这样做而失败。上面的过程类似于部署应用程序(手动),而我们自己创建它,并且不需要头疼,因为您没有通过向EVERYONE添加权限来调整注册表,这对生产服务器来说是一种安全风险。

我希望这有助于解决它。


2
投票

似乎有一个明显的解决方案,我还没有看到一个巨大的缺点,至少在获得管理权限以创建自己的事件源是不切实际的:使用已经存在的事件源。

我开始使用的两个是“.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{}包装它以防万一它失败并使事情变得更糟,但事件现在可以保存。


1
投票

与我们所有的2008服务器有类似的问题。安全日志完全停止工作,因为GPO使组Authenticated Users和读取权限远离密钥HKLM\System\CurrentControlSet\Services\EventLog\security

根据微软的建议将这一点放回去纠正了这个问题。我怀疑让所有经过身份验证的用户在更高级别阅读也会纠正您的问题。


1
投票

我遇到了类似的问题 - 在我的案例中,Source包含<>字符。 64位机器正在使用新的甚至log-xml基础我会说,这些字符(从字符串设置)创建无效的xml导致异常。可以说这应该考虑Microsoft问题 - 不正确处理Source(名称/字符串)。


1
投票

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

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

New-EventLog -LogName应用程序-Source TFSAggregator

我用它来解决codeplex中的Event Log Exception when Aggregator runs问题。


0
投票

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

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


0
投票

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


53
投票

问题是EventLog.SourceExists尝试访问EventLog\Security密钥,只允许管理员访问。

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

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_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]

0
投票

在web.config中尝试以下

 <system.web>

<trust level="Full"/>

</system.web>

-1
投票

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

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


-3
投票

重建解决方案对我有用


46
投票

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


8
投票

对我来说,只为整个'EventLog'分支授予'网络服务'的'读'权限。


7
投票

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

所以我作为管理员编写了一个编程的prog:它注册了事件源。然后我从VS内部开始进行开发和调试没有问题。

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


6
投票

我在这里尝试几乎所有东西来解决这个问题......我在这里分享帮助我的答案:

解决问题的另一种方法:

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

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

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


5
投票

我从一个作为计划任务运行的.NET控制台应用程序中发生了这个异常,我试图做同样的事情 - 创建一个新的事件源并写入事件日志。

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

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

4
投票

我遇到了同样的问题,但是我不得不上升到一个级别,让每个人都可以完全访问HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \ key,而不是去安全,这为我解决了问题。


3
投票

Windows 7 64位上的相同问题。以管理员身份运行解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.