【问题标题】:How do you pass user credentials from one process to another for Impersonation in .NET 1.1?在 .NET 1.1 中,如何将用户凭据从一个进程传递到另一个进程以进行模拟?
【发布时间】:2011-03-06 23:49:30
【问题描述】:
我有一个在特定用户帐户下运行的 Windows 服务(用 .NET 1.1 编写)和在多个服务器上运行的服务实例。
我想将用户凭据(用户名、密码、域)从 WinForms 应用程序传递给服务,并让服务在服务器的本地文件系统中读取/写入文件,以模拟传入的凭据。
传递用户名、域和密码并让 Windows 服务执行模拟是否更好?我看不到如何序列化 WindowsIdentity 并将其作为参数传递给服务,然后围绕 I/O 执行 Impersonate() 和 Undo()。
作为容器对象,System.Net.NetworkCredential 未标记为可序列化,因此传递三个单独的参数似乎是合乎逻辑的。我基本上是在使用KB306158 中的模拟例程。
【问题讨论】:
标签:
c#
.net
windows-services
impersonation
.net-1.1
【解决方案1】:
我不知道这与您的需求有多大的直接关系,但这是我在应用程序中使用的模拟代码的 sn-p,该应用程序在给定有效凭据的情况下访问远程机器的注册表和文件系统。 LogonUser 方法将用户名密码和服务器名作为参数,您可以通过您的 winform 应用程序传递。
edit 您必须在您的 winform 应用程序和在不同计算机上运行的服务之间设置一种进程间通信形式。抱歉,我认为这是一个关于如何模仿而不是如何向您的流程发送信息的问题。就 IPC 的方法而言,有很多选择。看看this site,它会提供比我能提供的更多信息。最好的选择是使用命名管道。
[DllImport("advapi32.dll",EntryPoint = "LogonUser", SetLastError = true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
IntPtr admin_token = IntPtr.Zero;
WindowsIdentity wid = WindowsIdentity.GetCurrent();
WindowsIdentity wid_admin;
WindowsImpersonationContext wic;
if (LogonUser(user, servername, pass, 9, 0, ref admin_token))
{
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
//do stuff with new creds here
}
【解决方案2】:
我不认为您可以将网络凭据对象直接传递给另一个进程,它基于底层的 windows api,我猜在让进程传递他们的身份验证令牌时会涉及到各种错误的 juju。
如果可能,我会采用您提到的方法,并将登录凭据(用户/密码)传递给服务,并让它使用这些凭据进行模拟。
【解决方案3】:
简短的回答是:根本不传递凭据。这种方法是不安全的。
相反,您应该寻求利用操作系统提供的安全机制来实现您想要做的事情。它被称为 SSPI(安全支持提供者接口)。使用它,进程交换一系列由操作系统级安全提供程序生成的令牌,以设置安全上下文,而无需在用户模式代码中传递凭据。
如果您能够升级您的服务以使用 .NET 3.5,您可以使用 WCF 来执行 IPC,并且经过适当配置,它会处理 SSPI 握手的细节,并直接启用模拟。
如果您坚持使用 .NET 1.1,请查看提供的文章和示例代码 here 和 here,它们展示了如何从托管代码调用 SSPI 并使用它来保护 .NET 远程处理通道.