如何将用户凭据从一个进程传递到另一个进程以进行 .NET 1.1 中的模拟?

发布于 2024-09-07 03:10:09 字数 436 浏览 2 评论 0原文

我有一个在特定用户帐户下运行的 Windows 服务(用 .NET 1.1 编写)以及在多个服务器上运行的服务实例。

我想将用户凭据(用户名、密码、域)从 WinForms 应用程序传递给服务,并让该服务在服务器的本地文件系统中读取/写入文件,模拟传入的凭据。

传递用户名、域和密码并让 Windows 服务执行模拟是否更好?我不知道如何序列化 WindowsIdentity 并将其作为参数传递以使服务然后围绕 I/O 执行 Impersonate() 和 Undo()。

作为容器对象,System.Net.NetworkCredential 未标记为可序列化,因此传递三个单独的参数似乎是合乎逻辑的。我本质上使用的是KB306158中的模拟例程。

I have a Windows Service (written in .NET 1.1) running under a specific user account and instances of the service running on several servers.

I would like to pass user credentials (username, password, domain) to the service from a WinForms application and have the service read/write files in the server's local file system impersonating the passed-in credentials.

Is it better to pass the username, domain, and password and have the Windows Service perform the Impersonation? I don't see how to serialize a WindowsIdentity and pass one as a parameter to have the service then perform the Impersonate() and Undo() around the I/O.

As a container object, System.Net.NetworkCredential is not marked serializable so passing the three individual parameters seems logical. I'm essentially using the Impersonation routine found in KB306158.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月牙弯弯 2024-09-14 03:10:09

简短的回答是:根本不传递凭据。这种方法是不安全的。

相反,您应该寻求利用操作系统提供的安全机制来实现您想要做的事情。它称为 SSPI(安全支持提供商接口)。使用此进程交换由操作系统级安全提供程序生成的一系列令牌,以设置安全上下文,而无需在用户模式代码中传递凭据。

如果您能够升级服务以使用 .NET 3.5,则可以使用 WCF 执行 IPC,并且经过适当配置,它将处理 SSPI 握手的详细信息,并直接启用模拟。

如果您无法使用 .NET 1.1,请查看提供的文章和示例代码 此处此处,显示如何调用 SSPI来自托管代码并使用它来保护 .NET 远程处理通道。

The short answer is: don't pass the credentials at all. That approach is insecure.

Instead you should be looking to leverage the secure mechanism provided by the OS for achieving what you are wanting to do. It is called SSPI (Security Support Provider Interface). Using this the processes exchange a series of tokens generated by an OS-level security provider, to set up a security context without the need for passing credentials in user mode code.

If you were able to upgrade your service to use .NET 3.5, you could use WCF to do the IPC, and, appropriately configured, it would take care of the details of the SSPI handshake, and enable impersonation straightforwardly.

If you are stuck with .NET 1.1, then take a look at the articles and sample code provided here and here, which show how to invoke SSPI from managed code and use it to secure a .NET remoting channel.

无妨# 2024-09-14 03:10:09

我不知道这与您的需求有多么直接的关联,但这是我在一个应用程序中使用的模拟代码片段,该应用程序在给定有效凭据的情况下访问远程计算机的注册表和文件系统。 LogonUser 方法将用户名密码和服务器名作为参数,您可以通过 winform 应用程序传递这些参数。

编辑 您必须在 winform 应用程序和单独计算机上运行的服务之间设置一种进程间通信形式。抱歉,我认为这是一个关于如何模拟的问题,而不是如何向您的进程发送信息的问题。就 IPC 的方法而言,有很多选择。看看此网站,它会提供比我更多的信息。最好的选择是使用命名管道。

[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
}

I dont know how directly this correlates to your needs but this is a snippet of the impersonation code I used in an application that accesses the registry and file system of remote machines given valid credentials. The LogonUser method takes username password and servername as args which you could pass via your winform app.

edit You will have to set up a form of inter-process communication between your winform app and the services running on the separate computers. My apologies I thought this was a question about how to impersonate not how to send information to your process. As far as methods for IPC go there are quite a few options. Take a look at this site, it will provide far more information than I can. Your best bet is going to be using named pipes.

[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
}
叹倦 2024-09-14 03:10:09

我不认为你可以将 Network Credential 对象直接传递给另一个进程,它基于底层的 Windows api,我猜测让进程传递其身份验证令牌会涉及各种不良的问题。

如果可能的话,我会采用您提到的方法,并将登录凭据(用户/通行证)传递给服务,并让它使用这些凭据进行模拟。

I don't think you can pass the Network Credential object directly to another process, it's based on an underlying windows api and I'm guessing there would be all kinds of bad juju involved in letting processes pass around their auth tokens.

I would take the approach you mentioned, if possible, and pass the log on credentials (user/pass) to the service and let it use those for the impersonation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文