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.
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.