我有一个在域(ACME.COM)上运行的服务(AcmeService),还有一个在另一个域(DISNEY.COM)上运行的用户。
[电子邮件保护]希望通过 AcmeService 进行身份验证。该服务知道 DISNEY.COM 域,并使用 DISNEY.COM 的已知凭证通过 LDAP 导入其本地用户数据库中的所有用户。
如果米奇发送了他的完全合格的用户名/密码,AcmeService 可以通过直接连接到 DISNEY.COM 域控制器(他已经知道)使用 LDAP 对他进行身份验证。
[电子邮件保护]也想使用 AcmeService 进行身份验证,但想使用集成安全性进行身份验证,因为他不太信任 AcmeService,不愿泄露密码。(在我的场景中,它使用 .Net NegotiateStream,它是 SSPI 的包装器)
我对这个问题的理解是,AcmeService 无法使用集成安全性对不属于其域(ACME.COM)的用户进行身份验证。
我认为一般的解决方案是在 ACME.COM 和 DISNEY.COM 之间建立传出信任关系,但在我的场景中这是不可能的。
如果用户位于外部域中且没有定义的信任关系,是否有解决方案允许 AcmeService 使用 SSPI 验证用户身份?如果该解决方案仅适用于 AcmeService 计算机,则可以。
我可能弄错了,但我的印象是可以使用 ksetup /addkdc 使用外部 MIT Kerberos 来做这样的事情。
任何想法?
谢谢
更新
客户端和 AcmeService 之间的通信已通过 TLS 进行保护(无需相互身份验证)。连接完成后,客户端知道他正在与真正的 AcmeService 通信(感谢 TLS),但他现在需要使用他的 DISNEY.COM 凭据向 AcmeService 验证他的身份,客户端证书在这里不是一种选择,AcmeService 只知道它之前导入的 ActiveDirectory 帐户。
NTLM (v2) 足以满足我的场景,但我不明白为什么 Kerberos 不可行。AcmeService 有一个 DISNEY.COM 帐户([电子邮件保护]) 可用于与 Kerberos 相互认证。
我认为问题在于,当尝试使用 SSPI 验证 disney.com 用户时,AcmeService 无法自动定位 DISNEY.COM 域的域控制器。AcmeService 机器需要知道 DISNEY.COM 控制器可以位于“dc.disney.com”。
以下是在 AcmeService 机器上运行 dcdiag 和 nltest 的结果:
dcdiag /s:dc.disney.com /u:disney.com\acmeuser /p:XXXX /test:LocatorCheck
Running enterprise tests on : disney.com
Starting test: LocatorCheck
Warning: DcGetDcName(GC_SERVER_REQUIRED) call failed, error 1722
A Global Catalog Server could not be located - All GC's are down.
Warning: DcGetDcName(PDC_REQUIRED) call failed, error 1722
A Primary Domain Controller could not be located.
The server holding the PDC role is down.
Warning: DcGetDcName(TIME_SERVER) call failed, error 1722
A Time Server could not be located.
The server holding the PDC role is down.
Warning: DcGetDcName(GOOD_TIME_SERVER_PREFERRED) call failed, error 1722
A Good Time Server could not be located.
Warning: DcGetDcName(KDC_REQUIRED) call failed, error 1722
A KDC could not be located - All the KDCs are down.
......................... disney.com failed test LocatorCheck
nltest /dsgetdc:disney.com
Getting DC name failed: Status = 1355 0x54b ERROR_NO_SUCH_DOMAIN
我需要的是一个像“register-domain /domain:DISNEY.COM /controller:dc.disney.com”这样的神奇命令,正如我之前所说,如果只有 AcmeService 能够验证 DISNEY.COM 用户就可以了,该解决方案不需要与 ACME.COM 域中的每个人都合作。
答案1
如果用户位于外部域并且没有定义的信任关系,是否有解决方案允许 AcmeService 使用 SSPI 对该用户进行身份验证?
不。
如果您只能使用 .NET NegotiateStream 类,那么您将在 NegotiateStream 类的 MSDN 文档中看到,[MS-NNS]:
.NET NegotiateStream 协议使用 SPNEGO(在 Kerberos 和 NTLM 之间选择)来确定要使用的底层安全协议。
所以您的选择是 NTLM 和 Kerberos。
[电子邮件保护]也希望使用 AcmeService 进行身份验证,但希望使用集成安全性进行身份验证,因为他不太信任 AcmeService,不愿意泄露他的密码。
那么 NTLM 就不行了。NTLM v1、v2 和具有会话安全性的 v2 都依赖于弱哈希算法,而且密码的哈希本质上与密码等效,因此我同意你的观点,使用 NTLM 对服务进行身份验证就是将某人的密码泄露给该服务。
所以现在你只剩下 Kerberos 了。而 Active Directory 实现的 Kerberos 不会对不受信任的域的凭据进行身份验证。
所以现在你没有选择了。
我认为一般的解决方案是在 ACME.COM 和 DISNEY.COM 之间建立传出信任关系,但在我的场景中这是不可能的。
您说得对,创建信任将允许一个 Kerberos 领域信任另一个 Kerberos 领域的身份验证机制,但由于您无法创建信任,因此您就是 SOL。
当您想要在客户端和服务器之间提供强大的相互身份验证并且不能使用 Kerberos 时,您可以使用 PKI、数字证书、TLS。
我通常会建议您探索 AD 联合服务,但如果您由于某种原因无法创建传统的 AD 信任关系,那么您也将无法创建联合信任。
所以我的建议是客户端证书。(Schannel)