【深度分析】关于SPN不正确导致SQL数据库连接失败

连接SQL Server数据库时发生报错“The target principal name is incorrect. Cannot generate SSPI context”,无法连接,可能是由于AD域中记录了错误的SPN,导致无法进行身份验证而连接失败。下文通过简述Kerberos认证过程、SPN的组成,引出由SPN错误引发报错的解决方法。

Kerberos认证

1. Kerberos认证步骤

Kerberos认证需要包含KDC(Key Distribution Center)、客户端用户、提供服务的服务器三个组件。其中KDC是域控的一部分,执行两个任务:认证服务(AS)、票据许可服务(TGS)

  • 当客户端用户登录到网络时,会向用户所在域的AS申请一个“票据请求票据”(TGT);
  • 当客户端要访问网络上某个资源时,需要出示TGT、认证码、SPN(Server Principal Name),借此从用户所在域的TGS获取session票据;
  • 客户端使用这个session票据和认证码向网络上的服务获取访问令牌,接下来就可以登录上该服务了。

2. 使用Kerberos身份验证的条件

  • 客户端和服务器需要加域,当客户端和服务器加入不同域时,两个域需要有相互信任关系;
  • 提供服务的服务器需要注册正确的SPN。

注:从Windows Server 2003开始默认使用Kerberos认证方式,当网络上没有注册SPN时,就会使用NTLM认证方式,这个步骤叫做NTLM Fallback;如果网络上有注册SPN,但这个SPN注册在了错误的账户下(例如不是SQL Server服务启动账号),则认证失败,且不会再次尝试NTLM认证。

SPN(Server Principal Name)

1.SPN的组成

SPN是服务器上所运行服务的唯一标示,每个使用Kerberos的服务都需要一个SPN,这样客户端才可以辨认这个服务。SPN需要注册在AD域的计算机账户或者域用户账户下。

一个SQL Server的SPN由以下元素组成:

服务类型: 标示了服务的泛用类。对于SQL Server而言,是MSSQLSvc。
主机: 有两种形式。一个是运行SQL Server的计算机的FQDN。还有一种就是SQL Server的计算机的netbios名字,俗称短名。
端口号/实例名: 服务所监听的计算机端口号。对于SQL Server而言,如果SQL运行在默认端口(1433)上,则端口号可以省略。

从SQL Server 2008开始,Kerberos可以支持TCP, Named Pipes和Shared Memory三种协议。因此对于SQL Server 2008我们也可以使用SQL Server的实例名来替代端口号(仅就命名实例而言)。

例如:

MSSQLSvc/myserver.corp.mycomany.com:1433

MSSQLSvc/myserver:1433

MSSQLSvc/myserver.corp.mycomany.com

MSSQLSvc/myserver:

MSSQLSvc/myserver.corp.mycomany.com:instancename

MSSQLSvc/myserver:instancename

注:推荐为FQDN和netbios都注册SPN。

2. 检查、添加、删除SPN

详细的使用方法参考微软官方文档:
https://docs.microsoft.com/zh-cn/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc731241(v=ws.11)

查询SPN:

在命令行输入:
Setspn -L
其中可以是计算机账户或者域用户账户。

--2f5af88f87ffaaa9a5ec04faa8e4e478.png

添加SPN:

在命令行输入:
Setspn -S MSSQLSvc/server4.main.local:1433

--619c23f544e9f61d52561b571f7e1f85.png

注:使用“Setspn -A”也可以添加SPN,但推荐使用“Setspn -S”,因为“Setspn -S”在添加前会检查域内是否存在相同的SPN,防止重复的SPN注册在不同的账户下。

命令行输入:
Setspn -X

也可以检查域内是否存在重复的SPN。

--cd346cd597fac3b028dc0812a2b8ae65.png

删除SPN:

在命令行输入:
Setspn -D MSSQLSvc/server4.main.local:1433

--21e3e8c0a394af07a3cf0abebbe68cdc.png

如何为SQL Server注册SPN

1. 数据库服务启动账户

使用Network Service或Local System

内置账户Network Service和Local System代表计算机本身,SPN需要注册在运行SQL Server的计算机账户下。但Network Service和Local System本身有权

使用域用户账户

一般域用户没有为自身注册SPN的权限,需要手动在该域用户账户下注册SPN;如果该域用户具有本地管理员或域管理员权限,则有权限为自身注册或删除SPN。

注:可以在域控中为特定账户添加注册SPN的权限,但官方不推荐这种做法。

2. 故障处理

文字开头提到的报错:“Cannot generate SSPI context”

--8628682d5a73b37ed047205872fc9667.png

本次处理的故障是由于更换了服务启动账户,旧的SPN注册在本地计算机账户下,更换后没有自动删除,导致域内存在不正确的SPN,无法完成Kerberos认证。

解决方法:

删除计算机账户下的SPN后,添加域用户账户下的SPN。操作步骤如下:

先查询SPN,命令行运行
Setspn -L server4

--6a9d2b6857492e0ea378d75c30c7a26c.png

确认存在错误的SPN,下一步删除,命令行执行

Setspn -D MSSQLSvc/server4.main.local:1433 server4

Setspn -D MSSQLSvc/server4.main.local server4

--d579be18f17e514292b9cd20b12231be.png

删除后再为域用户账户添加SPN,命令行执行

Setspn -S MSSQLSvc/server4.main.local user-c

Setspn -S MSSQLSvc/server4.main.local:1433 user-c

--e34d11fa9307f96d8de195553204d645.png

添加成功后,再次查询SPN确认,命令行执行

Setspn -L server4

Setspn -L user-c

--9bdadccfec2bb8a427999837638f2555.png

添加成功,检查报错是否还存在,在SSMS执行查询

select auth_scheme,* from sys.dm_exec_connections

--16b5e72fc33b43871f91ce01d0d0642f.png

连接成功,而且使用的是Kerberos认证。

3. 其他常见故障

"Login Failed for user ‘NT Authority\ANONYMOUS’ LOGON"

客户端可能正在使用Local System进行连接,而且SQL Server没有注册SPN,由于Local System账号继承自System Context而不是一个真实的user context,于是就被当成ANONYMOUS LOGON。

解决方法:在SQL Server服务启动账户下手动注册SPN。

"Login Failed for user ’ ', the user is not associated with a trusted SQL Server connection"

这种情况是客户端用户没能被SQL Server识别出:
如果客户端程序是运行在一个本机用户(非域用户)或者是一个非本机管理员权限的机器帐户(非local system)下,那么无论SQL Server是否有注册SPN,都会得到这个错误。

解决方法:
在服务器端创建一个和客户端用户“同用户名用密码”的本机账号,然后在SQL Server中赋予相应的登录权限。这就是所谓pass through的方式。此时你实际上是在使用SQL Server那台计算机的同名帐户来访问SQL Server和相关的其他资源。因此SQL Server机器上该帐户的权限设置决定了客户端的操作权限。

如果客户端应用程序是运行在一个域用户下的话,那么该错误就说明Kerberos的验证失败了,这往往是由于没有SPN或者SPN不正确造成的。

解决方法:
注册正确的SPN,或者删除相应SPN放弃使用Kerberos认证。

"Could not open a connection to SQL Server[1326]"

和上面提到的故障情况类似,但上面使用TCP连接,这里我们使用Named Pipe连接,解决方法一样。

"Login failed for user ‘$’ "

客户端可能在使用Local system或者Network service运行。

解决方法:
在SQL Server的login中添加一个"domain\machinename$"账号。其中Machinename是客户端的计算机名。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/783155.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可持久化可反悔贪心

接到上级通知,贪心思路假了,紧急需要调整思路 思路假了?考虑反悔 while(思路==false){cout<<"思路假了"<<endl;思路=true;cout<<"改对了"<<endl; }Sample Output 思路假了 改对了 思路假了 改对了 思路假了 改对了 思路假了 改…

使用 navigateTo 实现灵活的路由导航

title: 使用 navigateTo 实现灵活的路由导航 date: 2024/8/13 updated: 2024/8/13 author: cmdragon excerpt: 摘要:本文详细介绍 Nuxt.js 中的 navigateTo 函数,包括基本用法、在路由中间件中使用、导航到外部 URL 和新标签页打开链接的方法,以及参数详解和注意事项,展示…

神经网络之卷积篇:详解Padding

详解Padding 为了构建深度神经网络,需要学会使用的一个基本的卷积操作就是padding,让来看看它是如何工作的。如果用一个33的过滤器卷积一个66的图像,最后会得到一个44的输出,也就是一个44矩阵。那是因为33过滤器在66矩阵中,只可能有44种可能的位置。这背后的数学解释是,如…

ChatMoneyAI嘴替,高情商回复

本文由 ChatMoney团队出品会说话是一个人的优势,而会接话才是一个人的本事。现实中很多人有这样的困扰:朋友聚会、上门拜访以及和人聊天。是不是完全不知道如何回应,只会说“嗯”、“对”、“好”。这种回应方式,会让人没有和你聊下去的欲望,也容易把天聊死,从而错失大把…

ChatMoney智能体高情商接话神器

本文由 ChatMoney团队出品会说话是一个人的优势,而会接话才是一个人的本事。现实中很多人有这样的困扰:朋友聚会、上门拜访以及和人聊天。是不是完全不知道如何回应,只会说“嗯”、“对”、“好”。这种回应方式,会让人没有和你聊下去的欲望,也容易把天聊死,从而错失大把…

MySQL时区设置和查看

检查: 操作系统的时区 MYSQL的时区中国标准时间(CST) 在修改系统时间之后,重新启动MySQL服务器,以确保修改生效。mysql 时区查看‌MySQL时区设置查看全局和会话时区使用命令 SELECT @@global.time_zone, @@session.time_zone; 可以查看全局和会话的时区设置。 使用命令 SH…

vue3的defineAsyncComponent是如何实现异步组件的呢?

这篇文章我们将通过debug源码的方式来带你搞清楚defineAsyncComponent是如何实现异步组件的前言 在上一篇 给我5分钟,保证教会你在vue3中动态加载远程组件文章中,我们通过defineAsyncComponent实现了动态加载远程组件。这篇文章我们将通过debug源码的方式来带你搞清楚defineA…

从自建到云原生:数据管理的未来与变革

在数据技术不断演进的背景下,云数据库的崛起和云原生数据库的普及标志着数据库技术的显著变革。从最初的自建数据库模式到如今的云原生数据库,企业在数据管理上的选择变得更加丰富和灵活。云数据库不仅仅是对传统数据库技术的一个迁移,更是对其进行了一次全面的升级和优化。…

P9520 [JOISC2022] 监狱

P9520 [JOISC2022] 监狱 题目描述 有一棵 \(N\) 个节点的树,有 \(M\) 个囚犯,要从 \(S_i\) 走到 \(T_i\)。每一时刻可以发布一个命令让一名囚犯走到相邻的节点,要求任意时刻囚犯不能走到同一个节点上,求是否可以令每一个囚犯从 \(S_i\) 走到 \(T_i\)。 做法解析 首先我们可…

《软件性能测试分析与调优实践之路》(第2版) 读书笔记(一)总体介绍(上)-真正从性能分析与调优来看性能测试

《软件性能测试分析与调优实践之路》(第2版) 是清华大学出版社出版的一本图书,作者为张永清,全书共分为9章,如下图所示 图书介绍:《软件性能测试分析与调优实践之路》(第2版) 1、为什么需要性能测试与分析 1)、了解系统的各项性能指标,通过性能压测来了解系统能承受多大…