Reputation: 1272
I'm using the following Microsoft example. Every time the WindowsIdentity instance calls .Impersonate(), nothing happens. No error, no impersonation.
Both before and after the call, the current identity is always the AppPool identity.
I've also tried another example found online, the Impersonator class, and the same thing happens.
The only modification I've made to those examples is changing LOGON32_LOGON_INTERACTIVE to LOGON32_LOGON_NETWORK in the LogOnUser call, since using Interactive always returned a 0 error.
It's an ASP.NET 4.0 app running on a Win2k8 server trying to impersonate a user in AD.
EDIT:
I hadn't mentioned this originally, but I modified the Microsoft example and turned it into a class so that I can could it from my ASP.NET app. I also have impersonate=true
in web.config.
Upvotes: 0
Views: 2710
Reputation: 1272
Giving write access to the App_Data folder for the Users group fixed the issue. Not sure what that has to do with impersonation though.
Upvotes: 0
Reputation: 10203
I eventually found a helper class where I had done something similar a couple of years ago. The helper implements IDisposable, so just wrap your file access code in a "using" like this:-
using (Impersonate imp = new Impersonate())
{
// Code in here will run under the identity specified in the helper
}
And here is the code for the helper class (I've removed the "usings" to save some space). You'll notice the user account is hardcoded in the constructor:
internal class Impersonate : IDisposable
{
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private bool _disposed = false;
private WindowsImpersonationContext _context = null;
[DllImport("advapi32.dll")]
private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
internal Impersonate()
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
string domain = "<whatever>";
string username = "<whatever>";
string password = "<whatever>";
try
{
if (RevertToSelf())
{
if (LogonUserA(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
_context = tempWindowsIdentity.Impersonate();
}
}
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose any managed resources here.
}
// Stop the impersonation.
_context.Undo();
_disposed = true;
}
}
}
Give it a go and let me know how you get on...
Andrew
Upvotes: 1
Reputation: 1097
The example you link is for a console application. If you have an ASP.Net web application where you want your code to be executed under the security context of the visitor you can enable ASP.Net impersonation in the IIS authentication settings (in the IIS manager MMC snap in).
Upvotes: 0