Is there a simple out of the box way to impersonate a user in .NET?
So far I've been using this class from code project for all my impersonation requirements.
Is there a better way to do it by using .NET Framework?
I have a user credential set, (username, password, domain name) which represents the identity I need to impersonate.
Best Answer
"Impersonation" in the .NET space generally means running code under a specific user account. It is a somewhat separate concept than getting access to that user account via a username and password, although these two ideas pair together frequently. I will describe them both, and then explain how to use my SimpleImpersonation library, which uses them internally.
Impersonation
The APIs for impersonation are provided in .NET via the
System.Security.Principal
namespace:Newer code (.NET 4.6+, .NET Core, etc.) should generally use
WindowsIdentity.RunImpersonated
, which accepts a handle to the token of the user account, and then either anAction
orFunc<T>
for the code to execute.or
Older code used the
WindowsIdentity.Impersonate
method to retrieve aWindowsImpersonationContext
object. This object implementsIDisposable
, so generally should be called from ausing
block.While this API still exists in .NET Framework, it should generally be avoided, and is not available in .NET Core or .NET Standard.
Accessing the User Account
The API for using a username and password to gain access to a user account in Windows is
LogonUser
- which is a Win32 native API. There is not currently a built-in .NET API for calling it, so one must resort to P/Invoke.This is the basic call definition, however there is a lot more to consider to actually using it in production:
SecureString
when you can collect one safely via user keystrokes.The amount of code to write to illustrate all of this is beyond what should be in a StackOverflow answer, IMHO.
A Combined and Easier Approach
Instead of writing all of this yourself, consider using my SimpleImpersonation library, which combines impersonation and user access into a single API. It works well in both modern and older code bases, with the same simple API:
or
Note that it is very similar to the
WindowsIdentity.RunImpersonated
API, but doesn't require you know anything about token handles.This is the API as of version 3.0.0. See the project readme for more details. Also note that a previous version of the library used an API with the
IDisposable
pattern, similar toWindowsIdentity.Impersonate
. The newer version is much safer, and both are still used internally.