用 Net.Security.NegotiateStream 模拟

Impersonation with Net.Security.NegotiateStream

NegotiateStream class 的 MSDN documentation 说:

Using NegotiateStream, you can do the following.

  • Send the client's credentials to the server for Impersonation or Delegation.
  • Request server authentication.
  • Encrypt and/or sign data before transmitting it.

第一点是我想要做的 - 模拟远程客户端的用户帐户,但在服务器上。

但我不知道该怎么做,也找不到任何实际使用模拟的示例。所有的例子都只是设置标志说他们想要模拟,但他们实际使用的只是标识,即他们只是检查经过身份验证的用户的用户名或组成员资格——他们实际上并不充当远程用户(模拟)

所以这是我的代码:

Dim Client As TcpClient = Listener.AcceptTcpClient
Using AuthStream As New NegotiateStream(Client.GetStream, False)
                AuthStream.AuthenticateAsServer(Net.CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Impersonation)
                Dim ClientUser As New WindowsPrincipal(AuthStream.RemoteIdentity)
                'Now what?
End Using

一些例子似乎认为这样做与模仿是一样的:

Dim ClientUser As New WindowsPrincipal(AuthStream.RemoteIdentity)
Threading.Thread.CurrentPrincipal = ClientUser

但这和冒充完全不一样。这样做之后,该程序将无法访问只有经过身份验证的远程用户才能访问的文件。

那么我们如何使用从 NegotiateStream 获得的 Iidentity(或由此构建的 WindowsPrincipal)来实际进行模拟?

注意:这需要通过桌面应用程序或 windows 服务完成, 而不是 ASP.NET 应用程序或 WCF 服务。

刚刚意识到我们可以将从流中获取的 IIdentity 转换为 WindowsIdentity,然后使用它来进行模拟,如下所示:

            Using AuthStream As New NegotiateStream(Client.GetStream, False)
                AuthStream.AuthenticateAsServer(CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Impersonation)
                Dim ClientIdentity As WindowsIdentity = DirectCast(AuthStream.RemoteIdentity, WindowsIdentity)
                Using ClientContext As WindowsImpersonationContext = ClientIdentity.Impersonate
                    'Do stuff as the remote user here'
                End Using
            End Using

一旦我实现了客户端并运行它在测试域上,就需要对此进行测试,但我认为它应该可以工作。

编辑:经过测试,一切正常