用 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
一旦我实现了客户端并运行它在测试域上,就需要对此进行测试,但我认为它应该可以工作。
编辑:经过测试,一切正常
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
一旦我实现了客户端并运行它在测试域上,就需要对此进行测试,但我认为它应该可以工作。
编辑:经过测试,一切正常