SPN 和 UPN 唯一性

作者:Justin Turner,Windows 组的高级支持升级工程师

注意

本内容由 Microsoft 客户支持工程师编写,适用于正在查找比 TechNet 主题通常提供的内容更深入的有关 Windows Server 2012 R2 中的功能和解决方案的技术说明的有经验管理员和系统架构师。 但是,它未经过相同的编辑审批,因此某些语言可能看起来不如通常在 TechNet 上找到的内容那么精练。

概述

运行 Windows Server 2012 R2 的域控制器阻止创建重复的服务主体名称 (SPN) 和用户主体名称 (UPN)。 这包括还原或重新激活已删除对象或者将对象重命名是否会导致重复。

背景

重复服务主体名称 (SPN) 经常出现,会导致身份验证失败,并可能导致 LSASS CPU 利用率过高。 没有现成的方法可以阻止添加重复的 SPN 或 UPN。 *

重复的 UPN 值会破坏本地 AD 和 Office 365 之间的同步。

*Setspn.exe 通常用于创建新的 SPN,在功能上内置于随 Windows Server 2008 发布的版本中,该版本增加了重复项检查。

SEQ 表\* ARABIC 1:UPN 和 SPN 唯一性

功能 注释
UPN 唯一性 重复的 UPN 会破坏本地 AD 帐户与基于 Microsoft Entra ID 的服务(例如 Office 365)的同步。
SPN 唯一性 Kerberos 需要使用 SPN 进行相互身份验证。 重复的 SPN 会导致身份验证失败。

有关 UPN 和 SPN 唯一性要求的详细信息,请参阅唯一性约束

症状

在各种屏幕对话以及目录服务事件日志中的事件 ID 2974 中,会记录错误代码 8467 或 8468 或者其十六进制、符号或字符串等效代码。 仅在以下情况下才会阻止创建重复的 UPN 或 SPN:

  • 写入将由 Windows Server 2012 R2 DC 处理

SEQ 表 \* ARABIC 2:UPN 和 SPN 唯一性错误代码

十进制 Hex 符号 String
8647 21C7 ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST 操作失败,因为所提供的用于添加/修改的 SPN 值在林范围内不是唯一的。
8648 21C8 ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST 操作失败,因为所提供的用于添加/修改的 UPN 值在林范围内不是唯一的。

如果 UPN 不唯一,则创建新用户会失败

DSA.msc

你选择的用户登录名已在此企业中使用。 选择另一个登录名,然后重试。

显示一条消息的屏幕截图,该消息指出你选择的登录名已被使用。

修改现有帐户:

企业中已存在指定的用户登录名。 通过更改前缀或者从列表中选择不同的后缀来指定新登录名。

显示一条消息的屏幕截图,该消息指出企业中已存在你使用的登录名。

Active Directory 管理中心 (DSAC.exe)

尝试使用已存在的 UPN 在 Active Directory 管理中心创建新用户会返回以下错误。

显示一条消息的屏幕截图,该消息指出未创建新用户。

SEQ 图 \* 当由于 UPN 重复导致创建新用户失败时,AD 管理中心显示的 ARABIC 1 错误

事件 2974 源:ActiveDirectory_DomainService

显示的屏幕截图

SEQ 图 \* ARABIC 2 事件 ID 2974 和错误 8648

事件 2974 列出了阻止的值,以及已包含该值的一个或多个对象(最多 10 个)的列表。 在下图中可以看到,UPN 属性值 dhunt@blue.contoso.com 已存在于其他四个对象上。 由于这是 Windows Server 2012 R2 中的一项新功能,当下层 DC 处理写入尝试时,仍会在混合环境中意外创建重复的 UPN 和 SPN。

显示 ARABIC 2 事件 ID 2974 和错误 8648 的屏幕截图。

SEQ 图 \* ARABIC 3 事件 2974,其中显示了包含重复 UPN 的所有对象

提示

定期检查事件 ID 2974,以便:

  • 识别尝试创建重复 UPN 或 SPN 的行为
  • 识别已包含重复项的对象

8648 =“操作失败,因为所提供的用于添加/修改的 UPN 值在林范围内不是唯一的。”

SetSPN:

从 Windows Server 2008 版本开始,Setspn.exe 就已内置了重复 SPN 检测,使用“-S”选项时它会进行这种检测。 但是,你可以使用“-A”选项绕过重复 SPN 检测。 如果结合 -A 选项使用 SetSPN,当以 Windows Server 2012 R2 DC 为目标时,会阻止创建重复的 SPN。 显示的错误消息与使用 -S 选项时显示的错误消息相同:“找到重复的 SPN,正在中止操作!”

ADSIEDIT:

Operation failed. Error code: 0x21c8
The operation failed because UPN value provided for addition/modification is not unique forest-wide.
000021C8: AtrErr: DSID-03200BBA, #1: 0: 000021C8: DSID-03200BBA, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 90290 (userPrincipalName)

显示操作失败并出现错误代码 0x21c8 的屏幕截图。

SEQ 图 \* 阻止添加重复的 UPN 时 ADSIEdit 中显示的 ARABIC 4 错误消息

Windows PowerShell

Windows Server 2012 R2:

显示一条消息的屏幕截图,该消息指出操作失败。

从面向 Windows Server 2012 R2 DC 的 Server 2012 运行 PowerShell:

显示未知错误的屏幕截图。

在面向 Windows Server 2012 R2 DC 的 Windows Server 2012 上运行 DSAC.exe:

显示在以 Windows Server 2012 R2 DC 为目标时非 Windows Server 2012 R2 上发生的用户创建错误的屏幕截图。

SEQ 图 \* 以 Windows Server 2012 R2 DC 为目标时非 Windows Server 2012 R2 上发生的 ARABIC 5 DSAC 用户创建错误

显示在以 Windows Server 2012 R2 DC 为目标时非 Windows Server 2012 R2 上发生的用户修改错误的屏幕截图。

SEQ 图 \* 以 Windows Server 2012 R2 DC 为目标时非 Windows Server 2012 R2 上发生的 ARABIC 6 DSAC 用户修改错误

无法还原导致 UPN 重复的对象:

显示如何还原对象的屏幕截图。

显示由于为添加/修改操作提供的 UPN 值在林范围内不唯一,因此操作失败的屏幕截图。

当对象由于 UPN/SPN 重复而无法还原时,不会记录任何事件。

对象的 UPN 必须唯一才能还原该对象。

  1. 在回收站中识别对象上存在的 UPN

  2. 识别所有具有相同值的对象

  3. 删除重复的 UPN

使用 repadmin.exe 识别已删除对象上的有冲突 UPN

Repadmin /showattr DCName "DN of deleted objects container" /subtree /filter:"(msDS-LastKnownRDN=<NAME>)" /deleted /atts:userprincipalname
repadmin /showattr DCName "CN=Deleted Objects,DC=blue,DC=contoso,DC=com" /subtree /filter:"(msDS-LastKnownRDN=Dianne Hunt2)" /deleted /atts:userprincipalname

C:\>repadmin /showattr winbluedc1 "cn=deleted objects,dc=blue,dc=contoso,dc=com" /subtree /filter:"(msds-lastknownrdn=Dianne Hunt2)" /deleted /atts:userprincipalname
DN: CN=Dianne Hunt2\0ADEL:dd3ab8a4-3005-4f2f-814f-d6fc54a1a1c0,CN=Deleted Object
s,DC=blue,DC=contoso,DC=com
    1> userPrincipalName: dhunt@blue.contoso.com

若要识别具有相同 UPN 的所有对象:使用 Repadmin.exe

repadmin /showattr WinBlueDC1 "DC=blue,DC=contoso,DC=com" /subtree /filter:"(userPrincipalName=dhunt@blue.contoso.com)" /deleted /atts:DN

C:\>repadmin /showattr winbluedc1 "dc=blue,dc=contoso,dc=com" /subtree /filter:"(userPrincipalName=dhunt@blue.contoso.com)" /deleted /atts:DN
DN: CN=Administrator,CN=Users,DC=blue,DC=contoso,DC=com
DN: CN=xouser1,CN=Users,DC=blue,DC=contoso,DC=com
DN: CN=xouser10,CN=Users,DC=blue,DC=contoso,DC=com
DN: CN=xouser100,CN=Users,DC=blue,DC=contoso,DC=com
DN: CN=Dianne Hunt,OU=Marketing,DC=blue,DC=contoso,DC=com
DN: CN=Dianne Hunt2\0ADEL:dd3ab8a4-3005-4f2f-814f-d6fc54a1a1c0,CN=Deleted Objects,DC=blue,DC=contoso,DC=com

提示

repadmin.exe 中以前未记录的 /deleted 参数用于在结果集中包含已删除的对象

  • 打开 Active Directory 管理中心并导航到“全局搜索”

  • 选中“转换为 LDAP”单选按钮

  • 键入 (userPrincipalName=ConflictingUPN)

    • 将 ConflictingUPN 替换为有冲突的实际 UPN
  • 选择“应用”

显示“全局搜索”页的屏幕截图。

使用 Windows PowerShell

Get-ADObject -LdapFilter "(userPrincipalName=dhunt@blue.contoso.com)" -IncludeDeletedObjects -SearchBase "DC=blue,DC=Contoso,DC=com" -SearchScope Subtree -Server winbluedc1.blue.contoso.com

SPN 和 UPN 唯一性

如果需要还原该对象,需要从其他对象中删除重复的 UPN。 如果只有一个对象,使用 ADSIEdit 可以十分方便地删除重复项。 如果有多个对象存在重复项,则使用 Windows PowerShell 工具可能更方便。

若要使用 Windows PowerShell 将 UserPrincipalName 属性设为 null,请运行:

显示操作失败并出现错误代码 0x21c7 的屏幕截图。

注意

userPrincipalName 属性是单值属性,因此,此过程只会删除重复的 UPN。

重复的 SPN

当阻止添加重复 SPN 时 ADSIEdit 中显示的错误消息的屏幕截图。

SEQ 图 \* 阻止添加重复的 SPN 时 ADSIEdit 中显示的 ARABIC 8 错误消息

在目录服务事件日志中记录 ActiveDirectory_DomainService 事件 ID 2974。

Operation failed. Error code: 0x21c7
The operation failed
The attribute value provided is not unique in the forest or partition. Attribute:
servicePrincipalName Value=<SPN>
<Object DN> Winerror: 8467

显示阻止创建重复 SPN 时记录的错误的屏幕截图。

SEQ 图 \* 阻止创建重复 SPN 时记录的 ARABIC 9 错误

工作流

  • 如果 DC == GC

    • 无需外部调用,在本地即可满足查询条件

    • UPN 案例

      • 根据提供的 UPN 查询本地林范围的 UPN 索引(userPrincipalName;全局索引)

        • 如果返回的条目数 == 0 -> 写入继续

        • 如果返回的条目数 !=0 -> 写入失败

          • 是否记录事件

          • 同时返回扩展的错误:

            • 8648:

              ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST

    • SPN 案例

      • 根据提供的 SPN 查询本地林范围的 SPN 索引(servicePrincipalName;全局索引)

        • 如果返回的条目数 == 0 -> 写入继续

        • 如果返回的条目数 !=0 -> 写入失败

          • 是否记录事件

          • 同时返回扩展的错误:

            • 8647:

              ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST

  • 如果 DC != GC

    • 最好进行外部调用,但这并不重要,也就是说,这是一项尽力而为的唯一性检查

      • 仅当找不到 GC 时,才根据本地 DIT 继续检查

      • 记录事件以指示这种情况

    • UPN 案例

      • 是否针对最近的 GC 提交 LDAP 查询? 根据提供的 UPN 查询 GC 的林范围 UPN 索引(userPrincipalName;全局索引)

        • 如果返回的条目数 == 0 -> 写入继续

        • 如果返回的条目数 !=0 -> 写入失败

          • 是否记录事件

          • 同时返回扩展的错误:

            • 8648:

              ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST

    • SPN 案例

      • 是否针对最近的 GC 提交 LDAP 查询? 根据提供的 SPN 查询 GC 的林范围 SPN 索引(servicePrincipalName;全局索引)

        • 如果返回的条目数 == 0 -> 写入继续

        • 如果返回的条目数 !=0 -> 写入失败

          • 是否记录事件

          • 同时返回扩展的错误:

            • 8647:

              ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST

重新激活已删除的对象时,将检查现有 SPN 或 UPN 值的唯一性。 如果找到重复项,则请求失败。

  • 对于某些属性更改(例如 DNS 主机名、SAM 帐户名等),在进行修改时,SPN 会相应地更新。 在此过程中,将删除已过时的 SPN,并构造新的 SPN,然后将其添加到数据库。 触发此路径的必要属性修改是:

    • ATT_DNS_HOST_NAME

    • ATT_MS_DS_ADDITIONAL_DNS_HOST_NAME

    • ATT_SAM_ACCOUNT_NAME

    • ATT_MS_DS_ADDITIONAL_SAM_ACCOUNT_NAME

    • ATT_SERVER_REFERENCE_BL

    • ATT_USER_ACCOUNT_CONTROL

如果任何新的 SPN 值重复,则我们会使修改失败。 在上面的列表中,重要属性是 ATT_DNS_HOST_NAME(计算机名)和 ATT_SAM_ACCOUNT_NAME(SAM 帐户名)。

试试看:探索 SPN 和 UPN 唯一性

这是本模块中多个“试试看”活动中的第一个。 本模块没有单独的实验室指南。 “试试看”活动是自由形式的活动,让你可以在实验室环境中探索课程材料。 你可以选择按提示操作,或者摆脱脚本并使用自己的活动。

注意

  • 这是多个“试试看”活动中的第一个。
  • 本模块没有单独的实验指南。
  • “试试看”活动本质上是自由形式的活动,让你可以在实验室环境中探索课程材料。
  • 你可以选择按提示操作,或者摆脱脚本并使用自己的活动。
  • 虽然并非所有部分都提供“试试看”提示,但我们仍鼓励你在适当的情况下,在实验室中探索课程内容。

试着探索 SPN 和 UPN 的唯一性。 按照这些提示操作,或完成自己的活动。

  1. 使用 UPN 创建新用户

  2. 使用 SPN 创建帐户

  3. 使用先前已定义的 UPN 创建新用户,或更改现有帐户的 UPN。 对另一个帐户的 SPN 执行相同操作

    1. 使用已被使用的 UPN 填充现有用户帐户

      1. 使用 PowerShell、ADSIEDIT 或 Active Directory 管理中心 (DSAC.exe)
    2. 使用已被使用的 SPN 填充现有帐户

      1. 使用 Windows PowerShell、ADSIEDIT 或 SetSPN
  4. 观察错误

可选

  1. 与课堂讲师确认是否可以在 Active Directory 管理中心启用 AD 回收站。 如果可以,请继续下一步。

  2. 在用户帐户中填充 UPN

  3. 删除帐户

  4. 使用与已删除帐户相同的 UPN 填充其他帐户

  5. 尝试使用回收站 GUI 还原帐户

  6. 想象一下你在上一步骤中看到的错误。 (不会提供刚刚执行的步骤的历史记录)你的目标是完成帐户的还原。 例如,查看工作簿中的步骤。