如何排查“Cannot generate SSPI context”(无法生成 SSPI 上下文)错误消息

文章翻译 文章翻译
文章编号: 811889 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

本文分步介绍如何排查“Cannot generate SSPI context”错误消息最常见的根源。在下列情形中,您可能会收到此错误消息:
  • 正在与 SQL Server 建立连接。
  • 正在使用集成安全性。
  • 使用 Kerberos 执行安全委派。

了解 Kerberos 术语和服务主体名称

客户端计算机上的 SQL Server 驱动程序利用集成安全性来使用用户帐户的 Windows 安全令牌,以便成功连接到运行 SQL Server 的计算机。Windows 安全令牌从客户端委派到运行 SQL Server 的计算机。当使用下列某一配置将用户的安全令牌从一台计算机委派到另一台计算机时,SQL Server 驱动程序就执行了这一委派:
  • 命名管道上的 NTLM(不使用安全支持提供程序接口 [SSPI])
  • TCP/IP 套接字上的 NTLM(使用 SSPI)
  • TCP/IP 套接字上的 Kerberos(使用 SSPI)
安全支持提供程序接口 (SSPI) 是一组 Windows API,它们允许在任何普通数据传输层(如 TCP/IP 套接字)上进行委派和相互身份验证。因此,SSPI 允许运行 Windows 操作系统的计算机在任何可以传输原始字节数据的传输层上将用户安全令牌从一台计算机安全地委派到另一台计算机。

当 SSPI 使用 Kerberos 在 TCP/IP 上委派,而 Kerberos 不能完成将用户安全令牌成功委派到运行 SQL Server 的目标计算机上所必需的操作时,就会出现“Cannot generate SSPI context”错误。

安全支持提供程序接口为何选择 NTLM 或 Kerberos

Kerberos 使用一种称为服务主体名称 (SPN) 的标识符。您可以将 SPN 视为网络服务器资源中某个实例的唯一域或林标识符。您可以对一个 Web 服务、SQL 服务或 SMTP 服务使用 SPN。还可以使多个 Web 服务实例位于同一台具有唯一 SPN 的物理计算机上。

SQL Server 的 SPN 由下列元素构成:
  • 服务类:它标识一般的服务类。SQL Server 的服务类始终为 MSSQLSvc。
  • 主机:它是运行 SQL Server 的计算机的完全限定域名 DNS。
  • 端口:它是服务正在侦听的端口号。
例如,运行 SQL Server 的计算机的 SPN 通常为:
MSSQLSvc/SQLSERVER1.northamerica.corp.mycompany.com:1433
默认实例的 SPN 格式与命名实例的 SPN 格式不同。端口号用于将 SPN 与特定实例联系起来。

当客户端上的 SQL Server 驱动程序使用集成安全性连接到 SQL Server 时,客户端上的驱动程序代码会尝试使用 WinSock 网络 API 来解析运行 SQL Server 的计算机的完全限定 DNS。为了执行这一操作,该驱动程序代码会调用 gethostbynamegethostbyaddr WinSock API。如果计算机使用的是集成安全性,即使 IP 地址或主机名是作为运行 SQL Server 的计算机的名称传递的,SQL Server 驱动程序也仍然尝试解析计算机的完全限定 DNS。

当客户端上的 SQL Server 驱动程序解析运行 SQL Server 的计算机的完全限定 DNS 时,会使用相应的 DNS 创建该计算机的 SPN。因此,凡是与通过 WinSock 将 IP 地址或主机名解析为完全限定 DNS 的过程有关的问题,都有可能导致 SQL Server 驱动程序为运行 SQL Server 的计算机创建无效的 SPN。

例如,客户端 SQL Server 驱动程序可创建为已解析完全限定的 DNS 的无效 SPN 包括:
  • MSSQLSvc/SQLSERVER1:1433
  • MSSQLSvc/123.123.123.123:1433
  • MSSQLSvc/SQLSERVER1.antartica.corp.mycompany.com:1433
  • MSSQLSvc/SQLSERVER1.dns.northamerica.corp.mycompany.com:1433
当 SQL Server 驱动程序创建了无效 SPN 时,由于 SSPI 接口会尝试在 Active Directory 目录服务中查找该 SPN,因此身份验证仍然有效,但找不到该 SPN。如果 SSPI 接口找不到该 SPN,Kerberos 身份验证就不会执行。此时,SSPI 层就切换到 NTLM 身份验证模式,同时登录过程使用 NTLM 身份验证并且通常会成功。如果 SQL Server 驱动程序创建了有效的 SPN 但未分配相应的容器,则当它尝试使用却无法使用该 SPN 时,就会出现“Cannot generate SSPI context”错误消息。如果 SQL Server 启动帐户是一个本地系统帐户,相应的容器就是计算机名称。对于任何其他帐户,相应的容器是 SQL Server 启动帐户。由于身份验证将尝试使用它所找到的第一个 SPN,因此在为容器分配 SPN 时一定不要出差错。换句话说,一个 SPN 必须且只能分配给一个容器。

Kerberos 身份验证成功的关键因素是网络上的 DNS 功能有效。您可以使用 Ping 命令行实用工具来验证客户端和服务器上的这一功能。在客户端计算机上,运行以下命令来获取运行 SQL Server 的服务器的 IP 地址(其中,运行 SQL Server 的计算机的名称是 SQLServer1):
ping sqlserver1
要弄清楚 Ping 命令行实用工具是否解析了 SQLServer1 的完全限定 DNS,请运行以下命令:
ping -a IPAddress
例如:
C:\>ping SQLSERVER1

Pinging SQLSERVER1 [123.123.123.123] with 32 bytes of data:
	
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
	
Ping statistics for 123.123.123.123:
Packets:Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum =  0ms, Average =  0ms
C:\>ping -a 123.123.123.123
	
Pinging SQLSERVER1.northamerica.corp.mycompany.com [123.123.123.123] with 32 bytes of data:
	
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Reply from 123.123.123.123:bytes=32 time<10ms TTL=128
Ping statistics for 123.123.123.123:
Packets:Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum =  0ms, Average =  0ms

C:\>
命令 ping -a IPAddress 解析为运行 SQL Server 的计算机的正确完全限定 DNS 时,客户端解析也会成功。

SQL Server 服务主体名称的创建

这是 Kerberos 和 SQL Server 交互的关键部分之一。使用 SQL Server,您可以在下列某一帐户下运行 SQL Server 服务:本地系统帐户、本地用户帐户或域用户帐户。当 SQL Server 服务实例启动时,它会尝试使用 DsWriteAccountSpn API 调用在 Active Directory 中注册自己的 SPN。如果调用失败,事件查看器中会记录以下警告:

来源:MSSQLServer 事件 ID:19011 描述:SuperSocket 信息:(SpnRegister) :错误 8344。

有关 DsWriteAccountSpn 函数的更多信息,请访问下面的 Microsoft 网站:
http://msdn2.microsoft.com/en-us/library/ms676056.aspx

简要说明

如果您在本地系统帐户下运行 SQL Server 服务,SPN 会自动注册,并且 Kerberos 会与运行 SQL Server 的计算机成功交互。但是,如果您在域帐户或本地帐户下运行 SQL Server 服务,则创建 SPN 的尝试大多会失败,原因是域帐户和本地帐户没有设置自己的 SPN 的权限。当创建 SPN 失败时,即意味着没有为运行 SQL Server 的计算机创建 SPN。如果使用域管理员帐户作为 SQL Server 服务帐户进行测试,SPN 就会成功创建,因为存在创建 SPN 所必需的域管理员级的凭据。

由于您不可能使用域管理员帐户运行 SQL Server 服务(以规避安全风险),因此运行 SQL Server 的计算机无法创建自己的 SPN。所以,如果要在连接到运行 SQL Server 的计算机时使用 Kerberos,就必须手动为运行 SQL Server 的计算机创建一个 SPN。在域用户帐户或本地用户帐户下运行 SQL Server 时必须这样做。所创建的 SPN 必须分配给该特定计算机上的 SQL Server 服务的服务帐户。除非运行 SQL Server 的计算机使用本地系统帐户启动,否则 SPN 不能分配给该计算机容器。其中必须有且只能有一个 SPN,而且必须将它分配给相应的容器。它通常是当前的 SQL Server 服务帐户。不过,它是本地系统计算机帐户。

验证域

验证您登录的域与运行 SQL Server 的计算机所属的域能否通信。此外,该域中也必须有正确的名称解析。
  1. 如果登录域就是运行 SQL Server 的计算机所属的域,则使用 Windows 身份验证登录到 SQL Server。如果身份验证失败,表明 Windows 帐户或域帐户有问题,您必须加以解决。请与安全管理员或网络管理员联系,以验证此 Windows 帐户或域帐户是否有适当的权限。
  2. 如果登录域不是运行 SQL Server 的计算机的域,请检查域之间的信任关系。
  3. 检查服务器所属的域和用于连接的域帐户是否在同一个林中。只有在同一个林中 SSPI 才能起作用。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    274438 无法使用 Windows 2000 中两个林之间的 Kerberos 信任关系
  4. 启动 SQL Server 时使用“Active Directory 用户和计算机”中的“帐户可以委派其他帐户”选项。
  5. 使用 Windows 2000 Resource Kit 中的操纵帐户的服务主体名称 (SetSPN.exe) 实用工具。Windows 2000 域管理员帐户或 Windows 2003 域管理员帐户可以使用该实用工具控制分配给服务和帐户的 SPN。就 SQL Server 而言,有且只能有一个 SPN。该 SPN 必须分配给相应的容器:大多数情况下为当前 SQL Server 服务帐户,SQL Server 使用本地系统帐户启动时为计算机帐户。如果使用本地系统帐户登录并启动 SQL Server,会自动创建 SPN。但是,如果使用域帐户启动 SQL Server,或者只要更改用于启动 SQL Server 的帐户,就必须先运行 SetSPN.exe 以删除过期的 SPN,然后再添加有效的 SPN。有关其他信息,请参见 SQL Server 2000 联机丛书中的“安全帐户委派”主题。为此,请访问下面的 Microsoft 网站:
    http://msdn2.microsoft.com/en-us/library/aa905162(SQL.80).aspx
    有关 Windows 2000 Resource Kit 的更多信息,请访问下面的 Microsoft 网站:
    http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/default.mspx?mfr=true
  6. 验证是否在正确执行名称解析。名称解析方法可能包括 DNS、WINS、HOSTS 文件和 LMHOSTS 文件。 有关名称解析问题以及解决这些问题的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    169790 如何解决基本的 TCP/IP 问题
  7. 有关如何解决 Active Directory 的可访问性问题和防火墙问题的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    291382 有关 Windows 2000 DNS 和 Windows Server 2003 DNS 的常见问题
    224196 将 Active Directory 复制流量限制在特定端口

验证服务器环境

检查安装有 SQL Server 的计算机上的一些基本设置:
  1. 除非您已将 Service Pack 3(或更高版本)应用于 Windows 2000,否则运行 Windows 群集的基于 Windows 2000 的计算机不支持 Kerberos。因此,在 SQL Server 的群集实例上使用 SSPI 身份验证的任何尝试都可能会失败。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    235529 对基于 Windows 2000 服务器群集的 Kerberos 支持
  2. 验证服务器是否在运行 Windows 2000 Service Pack 1 (SP1)。 有关对基于 Windows 2000 的服务器的 Kerberos 支持的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    267588 连接到 SQL Server 2000 时显示“Cannot generate SSPI context”(无法生成 SSPI 上下文)错误消息
  3. 在某个群集上,如果用于启动 SQL Server、SQL Server Agent 或全文检索服务的帐户发生更改(如使用新密码),请按照下面 Microsoft 知识库文章中提供的步骤操作:
    239885 如何更改群集的 SQL Server 计算机的服务帐户
  4. 验证用于启动 SQL Server 的帐户是否有适当的权限。如果您使用的帐户不是本地管理员组的成员,请参见 SQL Server 联机丛书中的“建立 Windows 服务帐户”主题,以获得该帐户必须具有的权限的详细列表:
    http://msdn.microsoft.com/library/en-us/instsql/in_overview_6k1f.asp

验证客户端环境

验证客户端上的下列各项:
  1. 确保客户端上正确安装并启用了 NTLM 安全支持提供程序。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    269541 在 Windows NT LM 安全支持提供程序注册表项丢失的情况下连接到 SQL Server 时出现错误消息:“Cannot generate SSPI context”(无法生成 SSPI 上下文)
  2. 确定是否在使用缓存凭据。如果使用缓存凭据登录到了客户端,则从该计算机注销,等到可以连接到域控制器时再重新登录,从而避免使用缓存凭据。 有关如何确定是否在使用缓存凭据的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    242536 使用域缓存凭据登录时不警告用户
  3. 验证客户端和服务器上的日期是否有效。如果这两个日期相距甚远,则您的凭据可能被视为无效。
  4. SSPI 使用名为 Security.dll 的文件。如果任何其他应用程序安装了具有此名称的文件,则可能使用另一个文件来代替真正的 SSPI 文件。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    253577 PRB:错误:80004005 - MS ODBC SQL Server driver cannot initialize SSPI package(80004005 - MS ODBC SQL Server 驱动程序无法初始化 SSPI 程序包)
  5. 如果客户端上的操作系统是 Microsoft Windows 98,则必须在客户端上安装 Microsoft 网络客户端组件。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    267550 BUG:通过 TCP/IP 连接到 SQL Server 时出现“Assertion failed”(断言失败)

验证客户端网络实用工具

客户端网络实用工具 (CNU) 与 Microsoft 数据访问组件 (MDAC) 一起提供,可用于配置与运行 SQL Server 的计算机的连接。您可以使用 MDAC Cliconfg.exe CNU 实用工具配置连接:
  1. 在“常规”选项卡上,定义协议的方式因 MDAC 版本而异。对于较低版本的 MDAC,可以选择“默认”协议。在最新版本的 MDAC 上,当连接到 SQL Server 时,除了列表顶部的协议外,您还可以再启用一个或多个协议。因为 SSPI 只适用于 TCP/IP,所以您可以使用一个不同的协议(如命名管道)来避免错误。
  2. 选中 CNU 中的“别名”选项卡,以验证是否已为要尝试连接的服务器定义了别名。如果已定义了服务器别名,则检查为该计算机连接到 SQL Server 的方式所配置的设置。您可以通过删除别名服务器来查看行为是否有更改来验证这一点。
  3. 如果 CNU 上没有定义别名服务器,则为要连接的服务器添加别名。在您执行此任务时,您也显式定义了协议,同时还定义了 IP 地址和端口。

收集信息以打开 Microsoft 产品支持 (PSS) 案例

如果使用本文的排查步骤仍找不出问题原因,请收集以下信息并打开 Microsoft 产品支持 (PSS) 案例:

要获取 Microsoft 产品支持服务电话号码和支持费用信息的完整列表,请访问下面的 Microsoft 网站:
http://support.microsoft.com/contactus/?ws=support
  1. 从 SQL Server 生成 sqldiag 报告。有关更多信息,请参见 SQL Server 联机丛书中的“sqldiag 实用工具”主题。
  2. 捕获客户端上错误的屏幕快照。
  3. 在无法连接到 SQL Server 的节点上,从命令提示符下键入以下命令:
    net start > started.txt
    该命令在它从中运行的目录内生成一个名为 Started.txt 的文件。
  4. 将下面注册表项下的注册表项值保存在客户端计算机上:
    HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\MSSQLSERVER\CLIENT\CONNECTTO
  5. 在群集环境中,为群集的每一个节点获取以下注册表项的值:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\LMCompatibilityLevel
  6. 在群集环境中,查看每个群集服务器节点上是否存在以下注册表项:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTLMSsp
  7. 如果使用通用命名约定 (UNC) 名称(或群集上的 SQL 网络名称)从客户端连接到 SQL Server,请捕获结果。
  8. 如果从客户端对计算机名称(或群集上的 SQL 网络名称)执行 Ping 操作,请捕获结果。
  9. 保存用于启动每一项 SQL Server 服务(MSSQLServer、SQLServerAgent、MSSearch)的用户帐户的名称。
  10. 支持专业人员必须清楚 SQL Server 是配置为用于混合身份验证还是用于仅 Windows 身份验证。
  11. 检查能否使用 SQL Server 身份验证从同一个客户端连接到运行 SQL Server 的计算机。
  12. 检查能否使用命名管道协议连接。

如何手动创建 SQL Server 的服务主体名称

安全支持提供程序接口 (SSPI) 是用于 Kerberos 身份验证的 Microsoft Windows NT 安全性的接口,它支持 NTLM 安全支持提供程序的身份验证方案。当您登录到 Windows 域时,会在操作系统级别执行身份验证。Kerberos 身份验证仅适用于启用了 Kerberos 并正在使用 Active Directory 的基于 Windows 2000 的计算机。

SSPI 仅适用于使用 Windows 身份验证建立的 TCP/IP 连接。(Windows 身份验证也称为信任连接或集成安全性。)命名管道或多重协议连接不使用 SSPI。因此,您可以将客户端配置为从 TCP/IP 以外的协议进行连接来避免此问题。

当 SQL Server 客户端尝试将 TCP/IP 套接字上的集成安全性用于运行 SQL Server 的远程计算机时,SQL Server 客户端网络库会使用 SSPI API 执行安全委派。SQL Server 网络客户端 (Dbnetlib.dll) 会调用 AcquireCredentialsHandle 函数并为 pszPackage 参数传入“协商”。此操作通知下层的安全提供程序执行协商委派。在此上下文中,协商意味着在基于 Windows 的计算机上是尝试 Kerberos 身份验证还是 NTLM 身份验证。也就是说,如果运行 SQL Server 的目标计算机具有正确配置的关联 SPN,Windows 就会使用 Kerberos 委派。否则,Windows 就使用 NTLM 委派。

注意:请确认未使用名为“SYSTEM”的帐户启动任何 SQL Server 服务(MSSQLServer、SQLServerAgent、MSSearch)。关键字 SYSTEM 可能会与密钥发行中心 (KDC) 产生冲突。

参考

有关 Kerberos 和 SSPI 安全性工作原理的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
266080 Kerberos 常见问题解答
231789 Windows 2000 本地登录过程
304161 SSPI 相互身份验证显示在客户端而非服务器端
232179 Windows 2000 中的 Kerberos 管理
230476 Windows 2000 中常见 Kerberos 相关错误说明
262177 如何启用 Kerberos 事件日志记录
277658 PRB:域名与 SQL Server SPN 注册到的 NetBIOS 名称不同时 Setspn 失败
244474 如何在 Windows Server 2003、Windows XP 和 Windows 2000 中强制 Kerberos 使用 TCP 而不是 UDP
326985 如何解决 IIS 中与 Kerberos 相关的问题
要查看有关 Microsoft SQL Server 2000 安全性的白皮书,请访问下面的 Microsoft 网站:
http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sp3sec00.mspx

属性

文章编号: 811889 - 最后修改: 2013年7月16日 - 修订: 20.2
这篇文章中的信息适用于:
  • Microsoft SQL Server 2005 Standard Edition
  • Microsoft SQL Server 2005 Developer Edition
  • Microsoft SQL 2005 Server Enterprise
  • Microsoft SQL 2005 Server Workgroup
  • Microsoft SQL Server 2005 Express Edition
  • Microsoft SQL Server 2000 标准版
  • Microsoft SQL Server 2000 64-bit Edition
  • Microsoft Windows Server 2003 Standard Edition
关键字:?
kbsqldeveloper kbhowtomaster kbhowto KB811889
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com