无法从 ASP.NET 或 ASP 应用程序写入 Windows 事件日志

本文可帮助你解决从 ASP.NET 或应用程序服务提供商(ASP)应用程序写入 Windows 事件日志时可能会引发意外错误的问题。

原始产品版本: Internet Information Services 8.0 及更高版本
原始 KB 数: 2028427

现象

在 Internet Information Services 8.0 或更高版本上运行 ASP.NET 或旧版 ASP 应用程序。 应用程序将事件记录到 Windows 事件日志。 写入事件日志失败,并显示类似于以下示例的错误消息:

ASP.NET 应用程序

System.Security.SecurityException:不允许访问请求的注册表。
System.ComponentModel.Win32Exception:访问被拒绝
InvalidOperationException:无法打开源应用程序的日志。 可能没有写入访问权限。

旧版 ASP 应用程序

权限被拒绝。

原因

之所以出现此问题,是因为默认情况下,由于安全访问有限,应用程序的用户令牌没有写入 Windows 事件日志所需的用户权限。

解决方法

重要

此部分(或称方法或任务)介绍了修改注册表的步骤。 但是,注册表修改不当可能会出现严重问题。 因此,按以下步骤操作时请务必谨慎。 作为额外保护措施,请在修改注册表之前先将其备份。 如果之后出现问题,您就可以还原注册表。 有关如何备份和还原注册表的详细信息,请参阅:如何备份和还原 Windows 中的注册表

若要向线程标识提供所需的权限,请通过服务器计算机上的以下注册表项修改事件日志的安全性。 应选择应用程序正在写入的事件日志:

  • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\Application\CustomSD
  • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\System\CustomSD

CustomSD注册表值的类型为 REG_SZ,在安全描述符定义语言 (SDDL) 语法中包含安全描述符。 有关 SDDL 语法的详细信息,请参阅下面的“详细信息”部分中的链接

注意

若要构造 SDDL 字符串,有三种与事件日志相关的不同权限:读取、写入和清除。 这些权限对应于 ASCII 兼容编码 (ACE) 字符串的访问权限字段中的以下位:

  • 1 = 读取
  • 2 = 写入
  • 4 = 清除

重要

可以采用相同的方式配置安全日志。 但是,只能更改“读取”和“清除”访问权限。 仅对 Windows 本地安全机构(LSA)保留对安全日志的写入访问权限。

以下示例是一个示例 SDDL,显示应用程序日志的默认 SDDL 字符串。 访问权限(以十六进制为单位)为粗体:

O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x5;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x2;;;BA)(A;;0x2;;;LS)(A;;0x2;;;NS)

条目含义:

  • O:BA 对象所有者是内置管理员(BA)。
  • G:SY 主组是系统(SY)。
  • D: 它是自由访问控制列表(DACL),而不是审核条目或 SACL。
  • (D;;0xf0007;;;AN) 拒绝匿名(AN)所有访问。 (1=Read + 2=Write + 4=Clear)(此 SDDL 中的第一个 ACE 字符串)。
  • (D;;0xf0007;;;BG) 拒绝内置来宾(BG)所有访问权限。
  • (A;;0xf0005;;;SY) 允许系统读取和清除(1=Read + 4=Clear),包括 DELETE、READ_CONTROL、WRITE_DAC和WRITE_OWNER(由0xf0000指示)。
  • (A;;0x7;;;BA) 允许内置管理员读取、写入和 CLEAR。
  • (A;;0x7;;;SO) 允许服务器操作员读取、写入和 CLEAR。
  • (A;;0x3;;;IU) 允许交互式用户读取和写入。
  • (A;;0x3;;;SU) 允许服务帐户读取和写入。

添加正确的 ACE 字符串,以便网页可以访问事件日志。 如果网页以匿名方式运行(换句话说,在 IIS 中使用匿名身份验证运行),则必须为此注册表项授予 IUSR 或自定义匿名帐户适当的权限 CustomSD 。 如果经过身份验证的用户组在 Windows 集成身份验证上运行,则应具有所需的权限。

为此,请将以下条目追加到所选事件日志下的默认值 CustomSD

  • 对于经过身份验证的用户组(如果有 Windows 集成身份验证): (A;;0x0003;;;AU) 其中 AU = 经过身份验证的用户。

  • 对于 IUSR 或自定义配置的匿名帐户(如果有匿名身份验证),请找到该帐户的 SID,然后创建一个,类似于 (A;;0x3;;;S-1-5-21-1985444312-785446638-2839930158-1121) 计算机上最后一个字段是 IUSR 帐户的 SID。

  • 对于 IIS 上的 Windows 身份验证并使用特定用户帐户启用 ASP.NET 模拟,请找到该模拟帐户的 SID,然后创建一个 SDDL 字符串,如下所示: (A;;0x3;;;S-1-5-21-1985444312-785446638-2839930158-1121) 其中最后一个字段是模拟帐户的 SID。

若要授予组读取权限,请将以下内容添加到 CustomSD 当前 CustomSD 字符串末尾的值:
(A;;0x1;;;[Your Group Name/user account SID])

若要授予组读取和写入权限,请将以下内容添加到 CustomSD 当前 CustomSD 字符串末尾的值:
(A;;0x3;;;[Your Group Name/user account SID])

Windows Server 2008

相反,在 Windows 2008 服务器上,如果你向有问题的用户和组提供对所有事件日志的读取访问权限,则只需将它们添加到内置的事件日志读取器组。 但是,如果不想授予对所有事件日志的访问权限,则仍必须使用 SDDL,可以使用 WevtUtil 该日志。 以下示例演示如何定义对 System 事件登录 Windows 2008 Server 的访问权限:

  1. 打开命令提示符,运行以下命令,将系统注销的 SDDL 转储到 txt 文件。

    wevtutil gl system > C:\temp\out.txt
    
  2. 打开文本文件并复制 channelAccess: 条目

    channelAccess: O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x5;;;SO)(A;;0x1;;;IU)(A;;0x1;;;AU)(A;;0x1;;;SU)(A;;0x1;;;S-1-5-3)(A;;0x2;;;LS)(A;;0x2;;;NS)(A;;0x2;;;S-1-5-33)
    
  3. 将用户或组添加到此字符串,并运行以下命令以应用新的 SDDL。 将 O:BAG:XXXX 替换为在上一步中创建的 SDDL 字符串:

    wevtutil sl System /ca:O:BAG:XXXX
    

注意

编辑此值并重新启动计算机后,新设置将生效。 请务必充分了解 SDDL 以及在每个事件日志上放置的默认权限,然后再使用此过程。 此外,在生产环境中实现这些更改之前,请务必彻底测试任何更改,因为可能会意外地在事件日志上配置访问控制列表(ACL),这样任何人都无法访问它。

详细信息