我正在开发一个需要在双跳场景中进行委派的项目。我们有一个桌面客户端,使用net.tcp绑定连接到WCF服务,连接到另一台服务器上的SQL数据库。我们的目标是使用用户的凭据来访问SQL数据库。
WCF服务和SQL数据库都在同一个域用户下运行,该用户已为SQL数据库启用了委派。已遵循说明here,但没有成功。
现在,我们的日志中记录了一些细节:
SQL数据库上使用的登录名显示为运行WCF服务的用户,并使用Kerberos。
WCF服务器上使用的登录名显示为客户端的用户,但使用NTLM。
使用[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
或using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
会导致在WCF服务器上以客户端身份运行命令。这让我相信假冒行为正常。
那么,是什么原因可能导致第一跳回归到NTLM?我们怀疑这是一个SPN问题,但我们已经向共享域用户注册了WCF服务和SQL服务的SPN。此外,根据上面列出的说明,我们已将SQL服务设置为域用户的委托信任。
我们在WCF服务上使用EndpointIdentity.CreateSpnIdentity
来设置SPN,这是我们向域用户注册的SPN。
有什么建议吗?提前谢谢!
编辑:
我们发现了一些可能存在问题的问题 - 我们没有在客户端上使用EndpointIdentity.CreateSpnIdentity
。设置完成后,我们收到错误
“对SSPI的调用失败”,内部例外是“目标原则名称不正确”。但是我们在客户端和服务器中设置的SPN匹配,并且都匹配服务的主机名。如果我们将客户端和服务器SPN都设置为完全不同的东西,或者客户端指定的SPN与服务器的SPN不匹配,则身份验证将像以前一样回退到NTLM。我们已经对错误进行了研究,但找不到它的原因。有什么建议吗?
我们还执行了两种情况的数据包捕获 - 回退到NTLM以及当我们收到“调用SSPI失败”错误时。在这两种情况下,都会发送和接收类似的数据包,直到提到NTLM为止。另一方面,从客户端向服务器发送“TURN CHANNEL”包。除了服务器的IP地址之外,数据包不包含任何人类可读的内容,直到提到NTLM,并且发送用户名和计算机名称,或者发送“TURN CHANNEL”数据包,其中包含似乎是SPN的内容,并且可能包含主机名。似乎没有任何人类可读的错误代码或错误消息。关于在数据包中寻找什么的任何建议?
答案 0 :(得分:0)
我们发现了错误 - 客户端正在使用服务器的IP地址创建连接。将IP切换为完全限定的域名后,第一个跃点将始终使用Kerberos进行身份验证。
IP地址解析为我们在两个SPN中使用的相同字符串,但我想客户端在执行任何其他检查之前检查连接字符串是否与斜杠后面的SPN部分匹配。
我们使用网络服务和我们的域用户测试了我们的结果,只要SPN分别注册到计算机或用户,就没有问题。
希望这个答案会为他人节省一些时间和麻烦!
附加说明:虽然这为所有连接启用了Kerberos身份验证,但我们后来发现在我们的情况下这是不必要的。我们与数据库的部分连接不在模拟使用块内,这导致表读取失败。我们已经删除了所有委托和SPN相关的代码,数据库连接继续正常工作。我们的第一跳是使用NTLM。我们并不完全确定如何在SQL服务器上使用凭据,因为我们的连接似乎正是所谓的双跃点场景,它应该需要Kerberos和委派,但是很难说明什么是有效的。我怀疑它可能与位于this document的委托下的注释有关:
当客户端使用与后端服务上的Windows帐户对应的用户名和密码对前端服务进行身份验证时,前端服务可以通过重用客户端的用户来对后端服务进行身份验证名称和密码。这是一种特别强大的身份流形式,因为将用户名和密码传递给后端服务使后端服务能够执行模拟,但由于未使用Kerberos,因此不构成委派。委派时的Active Directory控件不适用于用户名和密码身份验证。
如果有人对其工作原因有任何其他建议,我很乐意听到。但是,我觉得不值得再打开另一个问题。