写入事件日志时发生System.Security.SecurityException
我正在尝试将Server 2003(和IIS6)中的ASP.NET应用程序移植到Server 2008(IIS7)。
当我尝试访问浏览器的页面时,我得到这个:
“/”应用程序中的服务器错误。
安全例外
说明:应用程序试图执行安全策略不允许的操作。 要授予此应用程序所需的权限,请联系您的系统pipe理员或在configuration文件中更改应用程序的信任级别。
exception详细信息:System.Security.SecurityException:未find源,但部分或全部事件日志无法search。 无法访问的日志:安全
源错误:
在执行当前Web请求期间生成未处理的exception。 有关exception的来源和位置的信息可以使用下面的exception堆栈跟踪来标识。
堆栈跟踪:
[SecurityException:未find源,但无法search部分或全部事件日志。 无法访问的日志:安全。]
System.Diagnostics.EventLog.FindSourceRegistration(String source,String machineName,Boolean readOnly)+562 System.Diagnostics.EventLog.SourceExists(String source,String machineName)+251
[剪断]
这些是我已经做的尝试和解决的事情:
-
授予“Everyone”对
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security
项的完全访问权限。 这工作。 但自然不能在生产上做到这一点。 因此,我在运行应用程序几分钟后删除了“Everyone”权限,并重新显示错误。 -
我在安装期间使用提升的权限在应用程序日志和安全日志中创build了源(并且我通过regeditvalidation了它),但是错误依然存在。
-
我给了应用程序完全信任级别在
web.config
文件(和使用appcmd.exe
),但无济于事。
有没有人有一个洞察力,可以在这里做什么?
PS:这是这个问题的后续。 我遵循给定的答案,但无济于事(见上面#2)。
要为EventLog/Security
密钥提供Network Service
读取权限(按照Firenzi和royrules22的build议),请遵循http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx
- 打开registry编辑器:
- select
Start
然后Run
- input
regedt32
或regedit
- select
-
导航/展开到以下registry项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security
-
右键点击这个条目并select权限
-
添加
Network Service
用户 -
给它读取权限
更新:上面的步骤在开发人员机器上没有问题,您不使用部署过程来安装应用程序。
但是,如果您将应用程序部署到其他机器上,请考虑在安装期间注册事件日志源,如SailAvid和Nicole 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") } } }
问题是EventLog.SourceExists
尝试访问EventLog\Security
密钥,只有pipe理员才能访问。
C#程序login到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);
但是,如果程序没有pipe理员权限,并且在EventLog\Application
下找不到密钥,则以下行将失败,因为EventLog.SourceExists
将尝试访问EventLog\Security
。
if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);
因此推荐的方法是创build一个安装脚本,它将创build相应的密钥,即:
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \ Application \ dotNET示例应用程序
然后可以删除这两行。
您也可以创build一个.reg
文件来创buildregistry项。 只需将以下文本保存到文件create.reg
:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App]
解决方法是在EventLog / Security密钥上给“networking服务”帐户读取权限。
我在VS2010下开发的一个控制台程序(从XP200下的VS2008升级)有一个类似的问题。我的prog使用EnLib做一些日志logging。 错误被解雇了,因为EntLib没有注册一个新的事件源的权限。
所以我开始一旦我的编辑前卫作为pipe理员 :它注册了事件源。 然后我从VS里面开始debugging,没有问题。
(你也可以参考http://www.blackwasp.co.uk/EventLog_3.aspx ,它帮助了我
对我来说,授予“NetworkService”对整个“EventLog”分支的“读”权限是有效的。
.NET应用程序应用程序作为一个计划任务运行时,我发生了这种exception,我试图做基本相同的事情 – 创build一个新的事件源,并写入事件日志。
最后,为在下面的键上运行任务的用户设置完整的权限对我来说是个窍门:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
我遇到了同样的问题,但我不得不上升到一个级别,并充分访问每个人到HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \键,而不是下降到安全性,这解决了我的问题。
我尝试几乎所有在这里解决这个问题…我在这里分享的答案,帮助我:
解决问题的另一种方法是:
- 在IIS控制台中,转到pipe理您的站点的应用程序池,并记下运行它的身份(通常是networking服务)
- 确保这个身份可以读取KEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Eventlog(rig-click,授权)
- 现在将此应用程序池的标识更改为本地系统,应用并切换回networking服务
凭证将被重新加载,并且EventLog可重复使用
在http://geekswithblogs.net/timh/archive/2005/10/05/56029.aspx ,谢谢Michael Freidgeim
仅供参考…我的问题是意外地select“本地服务”作为ProcessInstaller的属性的帐户,而不是“本地系统”。 只要提到任何谁按照MSDN教程的本地服务select显示第一,我没有密切关注….
我不是在IIS上工作,但是我有一个应用程序在2K8框中引发同样的错误。 它在2K3盒子上工作得很好,去图。
我的决议是“以pipe理员身份运行”给应用程序提升权利,一切工作愉快。 我希望这有助于你朝着正确的方向前进。
Windows 2008是权限/权限/提升真的不同于Windows 2003,gar。
在Windows 7 64位上同样的问题。 以pipe理员身份运行解决了问题。
嗨,我遇到了同样的问题,当我正在开发一个应用程序,并希望安装在远程PC上,我通过执行以下操作:
1)转到registry,find:HKLM \ System \ CurrentControlSet \ Services \ EventLog \ Application(??? YOUR_SERVICE_OR_APP_NAME ???)
请注意,“(??? YOUR_SERVICE_OR_APP_NAME ???)”是您在创build.NET部署时定义的应用程序服务名称,例如,如果您将新应用程序命名为“我的新应用程序”,则密钥为: HKLM \ System \ CurrentControlSet \ Services \ EventLog \ Application \ My New app
注2:取决于你正在写入的事件日志,你可以在你的DEV文件夹中find\ Application \(如上所述),或者(\ System)或(\ Security),这取决于你的应用程序正在写入什么事件,(\ Application)应该一直罚款。
2)上面的键,从菜单上; select“文件” – >“导出”,然后保存文件。 (注意:这将创build必要的registry设置,当应用程序需要访问此密钥才能写入事件查看器),新文件将是一个.REG文件,为了参数,将其称为“My New App.REG “
3)在PRODuction上部署时,请咨询服务器的系统pipe理员(SA),将“我的新App.REG”文件与应用程序一起移交,并要求SA安装此REG文件,一旦完成(以pipe理员身份)为您的应用程序创build密钥。
4)运行你的应用程序,它不应该访问除此键以外的任何其他内容。
问题现在应该解决了。
原因:
当开发一个将事件写入EventLog的应用程序时,如果找不到这个键,就需要在Eventlogregistry下面有一个KEY,它会尝试创build它,然后由于没有这个权限而失败。 上述过程类似于部署应用程序(手动),而我们正在自己创build这个应用程序,因为您不通过为生产服务器上的安全风险添加对每个人的权限来调整registry,所以无需头痛。
我希望这有助于解决它。
在使用System.Diagnostics.EventLog.WriteEntry(“SourceName”,“ErrorMessage”,EventLogEntryType.Error)时,需要在regEdit的HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Application下创build一个使用了源名称的新密钥。
所以基本上你的用户没有权限来创build密钥。 可以根据您在“应用程序池高级”设置中的“标识”值使用的用户执行以下操作:
- 运行RegEdit并转到HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog
-
右键单击EventLog键并selectPermissions …选项3.添加您的用户完全控制权限。
– 如果您使用的是“networking服务”,请添加networking服务用户
– 如果您使用的是“ApplicationPoolIdentity”,请添加IIS APPPOL {您的应用程序池的名称}(在search用户时使用本地机器位置)。
– 如果您使用“LocalSystem”,请确保用户具有pipe理员权限。 不build议安全漏洞。
-
对于HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Security重复从1到3的步骤
对于使用Visual Studio进行debugging,我使用“NetworkService”(它是ASP.NET用户),当网站发布时,我使用了“AppicationPoolIdentity”。
有一个类似的问题,我们所有的2008年服务器。 安全日志完全停止工作,因为GPO将组Authenticated Users和远离HKLM\System\CurrentControlSet\Services\EventLog\security
读取权限
根据微软的build议来回顾这个问题。 我怀疑给所有authentication的用户阅读更高的水平也将纠正你的问题。
我碰到类似的问题 – 在我的情况下源包含<
, >
字符。 64位机器正在使用新的偶数日志 – XML的基础我会说,这些字符(从string设置)创build无效的XML导致exception。 可以说这应该考虑微软的问题 – 不正确处理源(名称/string)。
虽然安装程序的答案是一个很好的答案,但是在处理你没有写的软件时并不总是可行的。 一个简单的答案是使用PowerShell命令New-EventLog ( http://technet.microsoft.com/zh-cn/library/hh849768.aspx )创build日志和事件源,
以pipe理员身份运行PowerShell并运行以下命令,更改所需的日志名称和来源。
New-EventLog -LogName 应用程序 – 来源TFSAggregator
我使用它来解决Aggregator从codeplex 运行问题时的事件日志exception 。
看起来似乎是一个明显的解决scheme,我还没有看到一个巨大的缺点,至less在获得pipe理权限以创build自己的事件源是不切实际的:使用已经存在的一个。
我已经开始使用的两个是“.Net运行时”和“应用程序错误”,这两者似乎都会出现在大多数机器上。
主要缺点是无法按该事件进行分组,而且您可能没有关联的事件ID,这意味着日志条目可能会加上前缀“来自源.Net的事件ID 0的描述运行时无法find….“如果你省略了,但日志进去了,输出看起来大致合理。
由此产生的代码看起来像这样:
EventLog.WriteEntry( ".Net Runtime", "Some message text here, maybe an exception you want to log", EventLogEntryType.Error );
当然,由于你总是有机会在没有任何原因的事件源的机器上,所以你可能想try {} catch{}
它包装它,以防万一它失败,事情变得更糟,但事件是现在可以保存。
我的应用程序安装在客户端Web服务器上。 我select了检查SourceExists
并在我的安装程序中运行CreateEventSource
,而不是在networking服务权限和registry中进行操作。
如果我的事件源没有创build,我也在应用程序的log.source = "xx"
中添加了一个try / catch来将其设置为已知的源代码(这只会在我热插拔.dll而不是重新创build时才会出现)安装)。
解决scheme非常简单 – 以pipe理员模式运行Visual Studio应用程序!
在web.config中尝试下面
<system.web> <trust level="Full"/> </system.web>
在VS中运行应用程序时,我遇到了这个问题。 我所要做的只是以pipe理员身份运行程序一次,然后我可以在VS内运行。
以pipe理员身份运行,只需在Windows资源pipe理器中导航到您的debugging文件夹。 右键单击该程序,然后select以pipe理员身份运行。
重build解决scheme为我工作