为 Kerberos 连接注册服务主体名称

适用于:SQL Server

若要将 Kerberos 身份验证用于 SQL Server,必须满足以下两个条件:

  • 客户端计算机和服务器计算机必须属于同一 Windows 域或在可信域中。

  • 服务主体名称 (SPN) 必须在 Active Directory 中进行注册,后者在 Windows 域中起到密钥分发中心的作用。 SPN 在注册后会映射到启动 SQL Server 实例服务的 Windows 帐户。 如果未进行 SPN 注册或注册失败,则 Windows 安全层无法确定与 SPN 关联的帐户,因而无法使用 Kerberos 身份验证。

    注意

    如果服务器无法自动注册 SPN,则必须手动注册 SPN。 请参阅 手动注册 SPN

可以通过查询 sys.dm_exec_connections 动态管理视图来验证连接使用的是否为 Kerberos。 请运行下面的查询并检查 auth_scheme 列的值,如果 Kerberos 已启用,该值应为 KERBEROS

SELECT auth_scheme
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;

提示

Microsoft Kerberos Configuration Manager for SQL Server 是一款诊断工具,可帮助解决与 Kerberos Configuration Manager for SQL Server相关的连接问题。 有关详细信息,请参阅 Microsoft Kerberos Configuration Manager for SQL Server

SPN 在身份验证过程中所起的作用

当应用程序打开连接并使用 Windows 身份验证时,SQL Server Native Client 会传递 SQL Server 计算机名称、实例名称和 SPN(可选)。 如果该连接传递了 SPN,则使用它时不对它做任何更改。

如果该连接未传递 SPN,则将根据所使用的协议、服务器名和实例名构造一个默认的 SPN。

在上面这两种情况下,都会将 SPN 发送到密钥分发中心以获取用于对连接进行身份验证的安全标记。 如果无法获取安全标记,则身份验证采用 NTLM。

SPN 是一个名称,客户端通过该名称唯一地标识服务实例。 Kerberos 身份验证服务可以使用 SPN 对服务进行身份验证。 当客户端想要连接到某个服务时,它将查找该服务的实例,并为该实例编写 SPN,然后连接到该服务并显示该服务的 SPN 以进行身份验证。

注意

本文中提供的信息还适用于使用群集的 SQL Server 配置。

Windows 身份验证是向 SQL Server 验证用户身份的首选方法。 使用 Windows 身份验证的客户端通过 NTLM 或 Kerberos 进行身份验证。 在 Active Directory 环境中,始终首先尝试 Kerberos 身份验证。

权限

当启动数据库引擎服务时,它将尝试注册服务主体名称 (SPN)。 假设启动 SQL Server 的帐户无权在 Active Directory 域服务中注册 SPN。 在这种情况下,此调用会失败,并且会在应用程序事件日志以及 SQL Server 错误日志中记录警告消息。

若要注册 SPN,数据库引擎必须在内置帐户(如 Local System [不建议使用] 或 NETWORK SERVICE)或有权注册 SPN 的帐户下运行。 可以使用域管理员帐户注册 SPN,但在生产环境中不建议这样做。 可以使用虚拟帐户或托管服务帐户 (MSA) 运行 SQL Server。 虚拟帐户和 MSA 都可以注册 SPN。 如果 SQL Server 不在上述任一帐户下运行,则启动时不会注册 SPN,此时,域管理员必须手动注册 SPN。

SPN 格式

SPN 格式支持在 TCP/IP、命名管道和共享内存上进行 Kerberos 身份验证。 所支持的命名实例和默认实例的 SPN 格式如下所示。

命名实例

  • MSSQLSvc/<FQDN>:[<port> | <instancename>],其中:

    • MSSQLSvc 是要注册的服务。
    • <FQDN> 是服务器的完全限定的域名。
    • <port> 是 TCP 端口号。
    • <instancename> = SQL Server 实例的名称。

默认实例

  • MSSQLSvc/<FQDN>:<port> | MSSQLSvc/<FQDN>,其中:

    • MSSQLSvc 是要注册的服务。
    • <FQDN> 是服务器的完全限定的域名。
    • <port> 是 TCP 端口号。
SPN 格式 说明
MSSQLSvc/<FQDN>:<port>1 使用 TCP 时访问接口生成的默认 SPN。 <port> 是 TCP 端口号。
MSSQLSvc/<FQDN> 使用除 TCP 之外的协议时访问接口生成的用于默认实例的默认 SPN。 <FQDN> 是完全限定的域名。
MSSQLSvc/<FQDN>:<instancename> 使用除 TCP 之外的协议时访问接口生成的用于命名实例的默认 SPN。 <instancename> 是 SQL Server 实例的名称。

1 SPN 格式不需要端口号。 多端口服务器或不使用端口号的协议仍然可以使用 Kerberos 身份验证。

对于 TCP/IP 连接,如果 SPN 中包括 TCP 端口,SQL Server 必须启用 TCP 协议,以便用户使用 Kerberos 身份验证进行连接。

自动注册 SPN

当 SQL Server 数据库引擎 的实例启动时,SQL Server 将尝试为 SQL Server 服务注册 SPN。 实例停止时,SQL Server 将尝试取消此 SPN 的注册。 对于 TCP/IP 连接,SPN 的注册格式为 MSSQLSvc/<FQDN>:<tcpport>。 命名实例和默认实例都注册为 MSSQLSvc,根据 <tcpport> 值来区分实例。

对于支持 Kerberos 的其他连接,命名实例的 SPN 注册格式为 MSSQLSvc/<FQDN>:<instancename>。 注册默认实例的格式为 MSSQLSvc/<FQDN>

若要授予 SQL Server 启动帐户注册和修改 SPN 的权限,请执行以下步骤:

  1. 在域控制器计算机上,前往“Active Directory 用户和计算机”

  2. 选择“查看”>“高级”。

  3. 在“计算机”下,找到 SQL Server 计算机,然后右键单击并选择“属性”。

  4. 选择“安全”选项卡,选择“高级”

  5. 如果列表中未列出 SQL Server 启动帐户,请选择“添加”来添加帐户。 添加帐户后,执行以下步骤:

    1. 选择帐户,然后选择“选择”

    2. 在“权限”下,选择“已验证写入 servicePrincipalName”。

    3. 向下滚动,然后在“属性”下选择以下选项:

      • 读取 servicePrincipalName
      • 写入 servicePrincipalName
    4. 选择“确定”两次。

  6. 关闭“Active Directory 用户和计算机”

如果服务帐户缺少执行这些操作所需的权限,在注册或取消注册 SPN 时可能需要进行手动干预。

手动注册 SPN

若要手动注册 SPN,可以使用内置于 Windows 中的 Setspn 工具。 setspn.exe 是一个命令行工具,你可通过该工具读取、修改和删除服务主体名称 (SPN) 目录属性。 您还可借助此工具查看当前 SPN、重置帐户的默认 SPN 以及添加或删除补充 SPN。

如需详细了解 Setspn 工具、所需权限以及它的用法示例,请参阅 Setspn

以下示例说明了用于为使用域用户帐户的 TCP/IP 连接手动注册 SPN 的语法:

setspn -S MSSQLSvc/myhost.redmond.microsoft.com:1433 redmond\accountname

注意

如果 SPN 已存在,则必须在重新注册该 SPN 之前将其删除。 可以将 Setspn-D 开关结合使用来完成此操作。 以下示例说明如何手动注册基于新实例的 SPN。 对于使用域用户帐户的默认实例,使用:

setspn -S MSSQLSvc/myhost.redmond.microsoft.com redmond\accountname

对于命名实例,请使用:

setspn -S MSSQLSvc/myhost.redmond.microsoft.com:instancename redmond\accountname

有关 Always On 可用性组配置的详细信息,请参阅侦听器和 Kerberos (SPN)

客户端连接

客户端驱动程序支持用户指定的 SPN。 但是,如果未提供 SPN,则会根据客户端连接类型自动生成 SPN。 对于 TCP 连接,会将 MSSQLSvc/FQDN:[<port>] 格式的 SPN 用于命名实例和默认实例。

对于命名管道和共享内存连接,会将 MSSQLSvc/<FQDN>:<instancename> 格式的 SPN 用于命名实例,MSSQLSvc/<FQDN> 格式用于默认实例。

将服务帐户用作 SPN

可将服务帐户用作 SPN。 可以通过 Kerberos 身份验证的连接属性指定服务帐户,并采用以下格式:

  • username\@domaindomain\username 用于域用户帐户

  • machine$\@domainhost\FQDN 用于计算机域帐户(例如 Local SystemNETWORK SERVICE)。

若要确定连接的身份验证方法,请执行下面的查询。

SELECT net_transport, auth_scheme
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;

身份验证默认值

下表说明根据 SPN 注册情况所使用的身份验证默认值。

场景 身份验证方法
SPN 映射到正确的域帐户、虚拟帐户、MSA 或内置帐户。 例如,Local SystemNETWORK SERVICE 本地连接使用 NTLM,远程连接使用 Kerberos。
SPN 是正确的域帐户、虚拟帐户、MSA 或内置帐户。 本地连接使用 NTLM,远程连接使用 Kerberos。
SPN 映射到不正确的域帐户、虚拟帐户、MSA 或内置帐户。 身份验证失败。
SPN 查找失败或未映射到正确的域帐户、虚拟帐户、MSA 或内置帐户,或者不是正确的域帐户、虚拟帐户、MSA 或内置帐户。 本地和远程连接使用 NTLM。

注意

“正确”表示注册的 SPN 映射到的帐户是当前运行 SQL Server 服务的帐户。

注释

专用管理员连接 (DAC) 使用一个基于实例名称的 SPN。 如果成功注册 SPN,则可以将 Kerberos 身份验证用于 DAC。 用户也可以选择将帐户名指定为 SPN。

如果在启动过程中 SPN 注册失败,将在 SQL Server 错误日志中记录此失败,而启动过程将继续进行。

如果在关闭时 SPN 取消注册失败,将在 SQL Server 错误日志中记录此失败,而关闭过程将继续进行。

后续步骤