Here's how impersonate the webapp user
try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Try impersonating the App Pool user
RevertToSelf();
// The next 3 steps are the important steps
WindowsIdentity wi = WindowsIdentity.GetCurrent();
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// Output WindowsIdentity
output.Write("--- RevertToSelf() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
// Output WindowsIdentity
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}
You can also use the LogonUser()
[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
/// <summary>
/// This will impersonate a user using the LogonUser() and return a handle
/// to the WindowsImpersonationContext
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <param name="domain"></param>
public WindowsImpersonationContext ImpersonateUser(string login, string
password, string domain)
{
// constants used by LogonUser() method
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
WindowsImpersonationContext wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
// return the WindowsImpersonationContext
return wic;
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
// start of try block
try
{
// Get current Identity
WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
// Output Current Principal
output.Write("--- CurrentPrincipal ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Impersonate a user
WindowsImpersonationContext wic
= ImpersonateUser("username", "password", "domain");
// Output WindowsIdentity
output.Write("--- ImpersonateUser() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
// Undo the impersonation and set the CurrentPrincipal back
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
// Impersonate back to original identity
currentIdentity.Impersonate();
output.Write("--- Impersonate() ---<br>");
output.Write("WindowsIdentity.GetCurrent().Name: "
+ WindowsIdentity.GetCurrent().Name + "<br>");
output.Write("Thread.CurrentPrincipal.Identity.Name : "
+ Thread.CurrentPrincipal.Identity.Name + "<br>");
}
catch (Exception ex)
{
// display diagnostic error information if exception occurs
output.Write("<div>");
output.Write("<b>Exception Type</b>: " + ex.GetType().ToString() + "<br>");
output.Write("<b>Exception Message</b>: " + ex.Message + "<br>" );
output.Write("<b>Stack Trace</b>:<br>" + ex.StackTrace.Replace("\n", "<br>"));
output.Write("</div>");
}
}
Eric said:
Hello,
I have a web app that uploads files to a file server (different box than the
web server). The application uses NT integrated authentication, but no users
should have permissions to the file server.
How can I use a fixed domain account to upload the files to the file server
while still preserving the users' Windows integrated authentication on the
web server?
Thank you,
Eric