I have an asp.net project where the request will delegate work to the background (via quartz.net). The web application is using windows authentication and impersonation.
I would also like to impersonate the current user on the background thread as well. I have read how to impersonate a user with a supplied domain name, username and password and calling out the kernel. That method works.
IntPtr token;
var successfullLogon = LogonUser(userName, password, domain, logonType, logonProvider, out token);
if(successfullLogon == false)
{
var errorCode = Marshal.GetHRForLastWin32Error();
Marshal.ThrowExceptionForHR(errorCode);
}
That works, but it requires me to either provide a specific username/password, or have the user enter their password. neither situation is ideal.
What I would like is to pass the token from the user's identity from the request to the background and then impersonate the user from this existing token. I read that I should be able to call DuplicateHandle,
var token = ((WindowsIdentity)Request.User.Identity).GetToken().ToInt64();
var token = new IntPrt(token from request);
IntPtr duplicate;
try
{
if(NaviteMethod.DuplicateToken(token, SecurityImpersonationLevel.Impersonate, out duplicate) == false)
{
var errorCode = Marshal.GetHRForLastWin32Error();
Marshal.ThrowExceptionForHR(errorCode);
}
using(var identity = new WindowsIdentity(duplicate))
using(var context = identity.Impersonate())
{
//do work
context.Undo();
}
}
finally
{
if(duplicate != IntPtr.Zero)
{
NaviteMethod.CloseHandler(duplicate);
}
}
But I get an exception Overlapped I/O operation is in progress
The NativeMethod calls come from this post: How do I pass credentials to a machine so I can use Microsoft.Win32.RegistryKey.OpenRemoteBaseKey() on it?
Is it possible to use the current user's token and impersonate that user on a background thread? If so how can this be done and are there any user access rights required for this to occur?
Unfortunately you cannot bypass the "LogonUser". One option is to use ASP.NET Impersonation. The second one you already have it if you replace the first two lines of your second code block with the first block code.