使用 Http.sys 注册 Kerberos 服务主体名称

不推荐使用本机 XML Web 服务。后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。

在使用 CREATE ENDPOINT 或 ALTER ENDPOINT 创建或修改 HTTP 端点时,需要指定身份验证类型,它用于对向该端点发送 HTTP SOAP 请求的用户进行身份验证。有关详细信息,请参阅 CREATE ENDPOINT (Transact-SQL)ALTER ENDPOINT (Transact-SQL)

可以使用 CREATE ENDPOINT ALTER ENDPOINT,按照下列方式配置端点以支持 Kerberos 身份验证:

  • 设置 AUTHENTICATION=KERBEROS,可将 Kerberos 用作唯一的 HTTP 身份验证方式

  • 当 AUTHENTICATION=INTEGRATED 时,该端点的 HTTP 身份验证可以提供下列选项来协助执行:NEGOTIATE、KERBEROS 和 NTLM。对于 NEGOTIATE 选项,客户端和服务器将尝试建立基于 Kerberos 的身份验证。如果客户端不支持 Kerberos 或者不可能进行协商,身份验证将退回到 NTLM。为防止在使用 NEGOTIATE 时客户端退回到 NTLM,建议客户端在端点上设置 AUTHENTICATION=KERBERO。

若要支持 Kerberos 下的相互身份验证,SQL Server 的实例必须将服务主体名称 (SPN) 与它将在其上运行的帐户(比如,Local System 帐户或域用户帐户)进行关联。由特定 SQL Server 实例进行 SPN 注册的具体细节由配置它时所用的服务帐户的类型确定。如果 SQL Server 正在以 Local System 帐户或 Network Service 帐户运行,则必须以计算机名称注册 SPN。如果 SQL Server 正在以域用户帐户运行,则必须以该域用户名注册 SPN。

使用 SetSPN.exe

若要使 SPN 与运行 SQL Server 实例的帐户关联,请使用 Windows SetSPN.exe 支持工具。该工具可以为正在以位于 Active Directory 中的 Windows 域服务用户帐户运行 SQL Server 实例的计算机名称添加 SPN。在此情形中,SetSPN.exe 工具可以用于添加两个 SPN:一个用于 NetBIOS 名称,另一个用于完全限定的 DNS 名称。

例如,如果从在 MyComputer 上运行的 SQL Server 实例执行 SetSPN.exe 工具,则以下两个 SPN 将与运行 SQL Server 实例的帐户关联,并且必须添加到目录中:

HTTP/MyComputer;
HTTP/MyComputer.fully.qualified.domain.name.com

请注意,一个帐户可以有多个 SPN,但是一个 SPN 只能注册到一个帐户。

若要删除两个相同的 SPN 名称(包括 NetBIOS 和完全限定的 DNS),也可以使用 SetSPN.exe。

注意事项

  • 与 Httpcfg.exe 类似,SetSPN.exe 也是由 Windows Server 2003 提供的,并且其安装过程与 Httpcfg.exe 和其他 Windows 支持工具的安装过程相同。有关详细信息,请参阅配置 HTTP 内核模式驱动程序 (Http.sys)

  • 如果 SQL Server 实例未以 Local System 帐户运行,则只有那些拥有 DOMAIN ADMIN 特权的集成身份验证用户才能通过使用 SetSPN.exe 工具更改 SPN 注册。

  • 如果 SQL Server 实例正在以 Local System 帐户运行,则只有 SQL Serversysadmin 固定服务器角色的成员才能通过使用 SetSPN.exe 工具更改 SPN 注册。

  • 如果服务帐户是本地系统,则无需使用 SetSPN.exe 工具即可将 SPN 添加到计算机的 Active Directory 帐户中。

SetSPN.exe 的语法

SetSPN.exe 的语法是:

setspn { -ASPN | -DSPN | -L } service_account

参数

  • -A
    将指定的 SPN 添加到帐户。

  • -D
    从帐户中删除指定的 SPN。

  • -L
    列出注册到帐户的所有 SPN。

示例

如果 SQL Server 实例是作为域用户 (MyDomain\MySQLAccount) 在名为 MySQLHost 的计算机上运行的,则可以使用下列命令设置相应的 SPN:

setspn –A http/MySQLHost MyDomain\MySQLAccount
setspn –A http/MySqlHost.Mydomain.Mycorp.com MyDomain\MySQLAccount

请注意,一个帐户可以有多个 SPN(每个服务名或主机名有一个),但是一个 SPN 只能注册到一个帐户。在多个帐户上注册同一个 SPN 将导致 Kerberos 身份验证失败。

例如,可以在帐户 MyDomain\MySQLAccount 上注册下列不同的 SPN。前两个命令用于两个不同的服务(http 和 rpc)。最后一个命令用于一个不同的主机名,假设该计算机有多个主机名。

setspn –A http/MySQLHost MyDomain\MySQLAccount
setspn –A rpc/MySQLHost MyDomain\MySQLAccount
setspn –A http/MySecondHost MyDomain\MySQLAccount

相反,以下情形将导致 Kerberos 失败:

setspn –A http/MySQLHost MyDomain\MySQLAccountOne
setspn –A http/MySQLHost MyDomain\MySQLAccountTwo

出现失败的原因是,在两个不同的服务帐户(MySQLAccountOne 和 MySQLAccountTwo)下运行的计算机上有两个 SQL Server 实例。不支持注册两个 SPN(每个 SQL Server 实例一个)。

当在不同帐户下的同一计算机上运行多个 SQL Server 实例时,就会出现这种情况。一个 SPN 只能注册到一个帐户。如果需要包括其他应用程序(如 IIS)在内的多个 SQL Server 实例(例如,Inst1Inst2)共存,并且希望将 HTTP Kerberos 身份验证用于所有服务,请使用下列方法之一解决 SPN 注册冲突:

  • 使所有实例和应用程序在同一帐户下运行。

    例如,使 Inst1Inst2 和 IIS 都在 LocalSystem 或 Mydomain\MyServiceAccount 下运行。

  • 为同一计算机注册多个主机名,并使每个实例和应用程序侦听不同的主机。因此,在这种情况下,必须执行下列操作:

    • 为计算机创建三个不同的主机名。

    • 将各个主机指派给不同的应用程序。

    • 注册三组 SPN,每个主机名/应用程序组合使用一组。

Kerberos SPN 注册问题疑难解答

下面是常见的 Kerberos SPN 注册问题的疑难解答:

  • SPN 未注册。

    如果某个 SPN 未注册,则 Kerberos 身份验证可在运行 SQL Server 实例的本地计算上正常工作,但在远程客户端计算机上将会失败。

  • 某 SPN 被多次注册。

    管理员有可能在域目录中复制了服务主体名称 (SPN),从而导致 Kerberos 身份验证失败的情形有以下几种。其中包括:

    • 对运行 SQL Server 实例的域帐户进行更改

      如果在某个域帐户(如 DOMAIN\User1)下运行 SQL Server 实例的同时运行了 SetSPN.exe,然后又更改了用于运行 SQL Server 的域帐户(如更改为 DOMAIN\User2),则当再次运行 SetSPN.exe 时,将会导致同一 SPN 插入到两个帐户下的目录中。

    • 安装运行在不同帐户下的多个 SQL Server 实例

      如果安装了多个 SQL Server 实例,然后在不同的帐户下运行各个实例,并且每个实例上均运行了 SetSPN.exe,则每个 SQL Server 服务帐户下的目录中都将会有重复的帐户。这对于运行在域用户和本地系统帐户下的实例均适用。

    • 在不同的帐户下删除并重新安装 SQL Server 实例

      如果在某个帐户下安装了 SQL Server,注册了 SPN,又在其他帐户下删除并重新安装了 SQL Server,然后又重新注册了 SPN,则每个域帐户将具有相同的 SPN。这意味着 SPN 将会重复。

在以上每种情形中,HTTP 端点都会退回到 NTLM 身份验证,除非解决此问题。这通常需要在目录中搜索重复或陈旧的 SPN 并手动删除它们。