Reputation: 3874
I want to read a pdf stored on a remote server. I have been provided with a username/password which has read access rights.
I am using ASP.NET impersonation given in this url https://support.microsoft.com/kb/306158
I am logging everything to a logFile just to help with debugging.
StreamWriter sw = new StreamWriter(Server.MapPath("~/log/logFile.txt"), true);
sw.WriteLine("Just before Impersonation");
if(impersonateValidUser("username", "domain", "password"))
{
try
{
byte[] bytes = File.ReadAllBytes(documentName);
sw.WriteLine("Bytes read!!");
undoImpersonation();
}
catch(Exception ex)
{
sw.WriteLine(ex.Message + "\n" + ex.StackTrace);
return;
}
else
{
sw.WriteLine("Impersonation Failed");
return;
}
In my log file, I just see the "Just before Impersonation". Neither of the messages of the try nor catch block is written to the log file. Surprisingly, I do not see the impersonation failed message.
Just wondering if anyone has previous experience with this kind of behavior? Is there any extra requirement to access file on a remote machine? I know that the remote machine does have advapi32.dll and kernel32.dll
Upvotes: 2
Views: 2200
Reputation: 44931
We had problems using the MSDN sample as well and if I recall correctly, it had to do with handles getting closed prematurely.
We ended up rewriting it in the following way, which has worked very well for us:
private void DoLogin()
{
var token = LogonAsUser(userName, domain, password);
if (!IntPtr.Equals(token, IntPtr.Zero))
{
WindowsImpersonationContext impersonatedUser = null;
try
{
var newIdentity = new WindowsIdentity(token);
impersonatedUser = newIdentity.Impersonate();
// Do impersonated work here
}
finally
{
if (impersonatedUser != null)
{
impersonatedUser.Undo();
}
LogonAsUserEnd(token);
}
}
}
private IntPtr LogonAsUser(String userName, String domain, String password)
{
IntPtr token = IntPtr.Zero;
if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
return token;
}
else
{
return IntPtr.Zero;
}
}
private void LogonAsUserEnd(IntPtr token) {
if (!IntPtr.Equals(token, IntPtr.Zero))
{
CloseHandle(token);
}
}
One other side note: we defined LogonUserA as returning a bool, not an int, which could also be part of the issue you are encountering.
Upvotes: 1