.net - EventLog.SourceExists 在 Windows Server 2019 上失败

标签 .net iis registry windows-server-2019

我正在使用 .Net Framework 4.7.2 在 Windows Server 2019 上测试 ASP.NET 应用程序。 IIS 应用程序设置为模拟没有管理权限的用户。

应用程序在尝试创建新源之前调用 EventLog.SourceExists 来检查事件日志源是否存在。据我所知,此方法需要管理权限才能搜索现有事件日志的来源 [1]。实现此目的的另一种方法是,我明确授予用户对注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog 和所有子项的读取权限。

这适用于 Windows Server 2019 之前的版本(2016、2012 R2、2018)。

测试时,同一应用程序在 Windows Server 2019 上失败,但出现异常。

The source was not found, but some or all event logs could not be searched. Inaccessible logs: State.

运行 procmon 时,尝试打开“状态”事件日志的注册表项时,我看到访问被拒绝 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\State

“State”注册表项对于 Windows Server 2019 来说是新的。它也受到保护 - 它由 SYSTEM 拥有,管理员仅限于只读。当我尝试授予我的用户读取权限时,我收到“访问被拒绝”的消息。因此,在调用 EventLog.SourceExists 时,以非管理员用户身份运行的应用程序会失败,并显示 Inaccessible logs: State

我意识到我可以取得 State 注册表项的所有权并添加我的用户。不过,在执行此操作之前,我想看看是否有人了解 Windows Server 2019 中的这个新注册表项(事件日志)。

谢谢。

[1] https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.eventlog.sourceexists?view=netframework-4.7.2

最佳答案

根本原因:

HKLM\SYSTEM\CCS\Services\EventLog 树中的“状态”配置单元具有奇怪的安全配置。因此,任何尝试枚举事件源的应用程序最终都会遇到“访问被拒绝”异常并退出。

默认权限是:

  • 系统(完全控制)
  • 事件日志(完全控制)
  • 管理员(读取 key )

它们不是继承的,就像“安全”配置单元一样。 相反,名为“Parameters”的第二个新配置单元继承权限。

枚举通常在应用程序中完成,如下所示:

[System.Diagnostics.EventLog]::SourceExists("Source Name")

即使您尝试使用 PowerShell 进行枚举,也会遇到“访问被拒绝”的情况

PS C:\> (gci -Recurse HKLM:\System\CurrentControlSet\services\eventlog).Name

虽然我不知道“状态”配置单元到底在做什么(微软对此不是很详细),但我找到了解决这个问题的方法。

解决方案:

  1. 交互式解决方案,使用 REGEDIT:

    a) 使用“PSexec”以系统身份运行 REGEDIT 并 b) 使用 REGEDIT 的 UI,向 IIS_IUSRS 的“状态”配置单元或您的服务或 IIS 应用程序池运行的任意帐户授予读取权限

  2. 使用 PowerShell 的脚本方法:

    a) 使用“PSexec”以系统身份运行 PowerShell 并 b) 使用“Get-ACL”/“Set-ACL”cmdlet,向 IIS_IUSRS 或您的服务或 IIS 应用程序池运行的任意帐户的“状态”配置单元授予读取权限

以 SYSTEM 用户身份运行应用程序的最佳方式是使用 PSexec,可以从 Microsoft SysInternals 站点 ( https://learn.microsoft.com/en-us/sysinternals/downloads/psexec ) 免费下载 PSexec

PS C:\> PSexec.exe -accepteula -d -i -s powershell.exe

这将打开一个以 NT AUTHORITY\System 身份运行的 PowerShell 窗口。 从此处,使用 REGEDIT 更改“状态”配置单元上的服务用户帐户或 IIS 应用程序池用户的权限。或者,使用 Get-ACL/Set-ACL cmdlet 以脚本化方式执行相同操作。 “读取 key ”权限足够;不需要“完全控制”。

PS C:\> $hive = HKLM:\System\CurrentControlSet\services\eventlog\state; $acl = Get-ACL $hive; $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("IIS_IUSRS","ReadKey","ContainerInherit","None","Allow"); $acl.SetAccessRule($rule); $acl |Set-ACL $hive

您的应用程序现在应该能够枚举其运行的计算机上的所有事件源,并创建事件源(如果枚举未找到)。

关于.net - EventLog.SourceExists 在 Windows Server 2019 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54874695/

相关文章:

c++ - 从服务应用程序访问 guest 帐户系统注册表配置单元

wix - Windows 应用程序注册表设置和指南

c# - Excel 插入行(不是添加)

c# - 在 C# XNA 游戏中用鼠标单击时移动图像

.net - 如何扫描磁盘上真正巨大的文件?

iis - Windows Server 2008 Web Edition 附带的 IIS 版本是什么

iis - 通配符 SSL 证书在未使用子域时生成错误

c# - 与在 Sql Server 上执行的 .NET 存储过程相关的开销是多少?

asp.net - default.aspx 中的 "StartTag: invalid element name"

python - 如何解码 REG_BINARY 值 HKLM\Software\Microsoft\Ole\DefaultLaunchPermission 以查看哪些用户拥有权限?