如何根据域validation用户的caching凭据?

当您login到Windows时,您的凭据被caching 。 这使您可以使用单点login 。 如果您之后要浏览另一台电脑,例如:

\\hydrogen 

在这里输入图像说明

您将不会被提示input凭据。

Windows将采取您的:

  • 当前用户名
  • (散列)密码

并尝试自动validation您的身份。 有趣的是,如果你的工作站不在域上,甚至可以工作。 连接到服务器时,Windows将自动使用您的用户名和密码。 如果你的:

  • 本地用户名/密码匹配一个
  • 用户名/密码

你自动进入。

美丽的照片:

在这里输入图像说明

这被称为单一login 。 您只需login一次Windows,并使用caching的凭据在networking上使用其他信息时validation您的身份。

浏览器也做到这一点

Chrome,Internet Explorer和Firefox也对此做了一些变化。 如果您需要login到网站,并且服务器支持协商授权,则服务器将向您发送一个指示,告知您应该尝试用户的Windows / Domain / Kerberos凭据:

 HTTP/1.1 401 Unauthorized Server: Microsoft-IIS/7.5 WWW-Authenticate: Negotiate Date: Thu, 09 Jul 2015 14:35:58 GMT Content-Length: 0 

然后,Chrome会将您的caching凭据,(在一些中间魔术后)转发到networking服务器:

 GET http://hr.woodglue.com HTTP/1.1 Host: hr.woodglue.com Authorization: Negotiate YIIFzwYGKwYBBQUCoIIFwzCCBb.... 

在这里输入图像说明

微软在旧文章的Internet Explorer中谈到了这种机制:

使用协商协议的基于HTTP的跨平台validation

在这里输入图像说明

  • 客户端使用SPN调用AcquireCredentialsHandle()InitializeSecurityContext()以构build请求来自TGS / KDC的会话票证的安全上下文。

您validation一个域,而不是服务器

我想提到的最后一点是,服务器,Web服务器,工作站,文件服务器不会根据服务器validation凭据,它们会根据域控制器进行validation。 你有许多域名服务器的模糊森林 ,其中一个处理你的请求。

换句话说,您不要validation凭据:

  • \\uranium woodglue.com域上的域控制器)

您validation凭据:

  • woodglue.com域名

我们有一个重要的概念,有人可以:

  • validation您的caching凭据
  • 对一个域
  • 而不必input用户名或密码

我怎样才能做到这一点?

我如何validation某人的caching凭据? 我怎样才能:

  • validation用户的caching的凭据
  • 对一个
  • 用户不必input用户名或密码(即使用Windowscaching凭证)

重要的一点是不知道(或关心):

  • 如果用户的机器join到域中
  • 如果用户的机器join工作组
  • 如果用户的机器join了woodglue.com或其他域名(例如woodglue.com
  • superglue.com域供电的服务器的名称

在这里输入图像说明

我不知道该怎么做
我不知道涉及哪些API技术。

我知道有一个叫做安全支持提供者接口 (SSPI)的API。 这就是WWW-Authenticate: Negotiate (尽pipe我不知道这是从一个非域join的PC为SMB供电的东西)。

Chromium的开放源代码可能能够从他们的http_auth_sspi_win.cc摘录一个片段。 他们使用SSPI函数AcquireCredentialsHandle

 int AcquireDefaultCredentials(CredHandle* cred) { TimeStamp expiry; // Pass the username/password to get the credentials handle. // Note: Since the 5th argument is NULL, it uses the default // cached credentials for the logged in user, which can be used // for a single sign-on. SECURITY_STATUS status = library->AcquireCredentialsHandle( NULL, // pszPrincipal const_cast<SEC_WCHAR*>(package), // pszPackage SECPKG_CRED_OUTBOUND, // fCredentialUse NULL, // pvLogonID NULL, // pAuthData NULL, // pGetKeyFn (not used) NULL, // pvGetKeyArgument (not used) cred, // phCredential &expiry); // ptsExpiry } 

传递用户名/密码以获取凭证句柄。

注意:由于第五个参数是NULL,因此它使用login用户的默认caching凭据,可以将其用于单一login。

AcquireCredentialsHandle “出站”调用是通过调用InitializeSecurityContext 。 这个想法是, InitializeSecurityContext生成一个代表客户端的不透明blob。

然后,您可以执行一组并行的调用:

  • “入站”调用AcquireCredentialsHandle
  • 调用AcceptSecurityContext ,从InitializeSecurityContext传递前面返回的blob

窃取 重做丹尼尔Doubrovkine的优秀形象 :

在这里输入图像说明

注意 :在这种情况下, “客户端”“服务器”用于指生产者和消费者的上下文。 在我的情况下, “客户端”“服务器”是在同一台机器上。

但是, “显示研究工作”这一行分崩离析,因为我没有看到在InitializeSecurityContext中的任何地方,我可以指定woodglue.com作为validation的域。

我知道InitializeSecurityContext联系kerberos服务器,并获得一个“票” blob。 然后,通过AcceptSecurityContext票证Blob传递给“服务器”。 有时候blob可以通过networking传递; 在我的情况下,它在同一台机器上的内存中传递。

但我不明白如何指定它应该联系该票的域服务器。

不要暗示SSPI对解决我的问题完全有用。 这只是“研究努力”

较早的研究努力

  • 调用InitializeSecurityContext(Negotiate)时要使用什么TargetName?
  • 如何validation域凭据(从本机代码)?
  • 使用哈希validation用户的密码?
  • Win32:如何根据Active Directoryvalidation凭据?
  • 如何执行Windows身份validation?

当然,在这一切中,如果caching的凭据在指定的域上无效,我将不得不提示用户input用户名和密码。 但用户名和密码是邪恶的,计算的祸害,我想避免它们。

我使用本机代码; 不是C#。