matt23lucier
MIS
I just read about impersonation and I thought that it could help me solve a problem I am having. I have an application that needs get and display the file names that are under a folder on our network. The problem is most users who are running the application do not have access to the folder and therefore when they try and get the contents they get an access denied error. I decided that I would try and get the application to impersonate a user account that has access to this folder prior to them attempting to read the contents. I found some code on the web but I cannot get it to work. I just keep getting access denied even when I impersonate a user who has the proper privileges:
Here is an example of the code I am using:
Impersonator imp = new Impersonator(txtUser.Text,txtDomain.Text,txtPassword.Text);
imp.Impersonate();
FileInfo[] fil = (new DirectoryInfo(")GetFiles();
for(int i = 0 ; i < fil.Length ; i++)
{
lstFiles.Items.Add(fil.Name.ToString());
}
imp.Undo();
NOW HERE IS THE CLASS IMPERSONATOR THAT I DOWNLOADED TO TRY AND USE:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
namespace Mariner.WebParts.Security
{
/// <summary>
///Jay Nathan - MARINER, LLC. - ///Impersonator class allows client code to impersonate another domain user account by handling underlying account authentication and security context manipulation
/// </summary>
public class Impersonator
{
// private members for holding domain user account
credentials
private string username = String.Empty;
private string password = String.Empty;
private string domain = String.Empty;
// this will hold the security context for reverting back to the client after impersonation operations are complete
private WindowsImpersonationContext impersonationContext = null;
// disable instantiation via default constructor
private Impersonator()
{}
public Impersonator(string username, string domain, string password)
{
// set the properties used for domain user account
this.username = username;
this.domain = domain;
this.password = password;
}
private WindowsIdentity Logon()
{
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// attempt to authenticate domain user account
bool logonSucceeded = LogonUser(this.username, this.domain, this.password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
if(!logonSucceeded)
{
// if the logon failed, get the error code and throw an exception
int errorCode = Marshal.GetLastWin32Error();
throw new Exception("User logon failed. Error Number: " + errorCode);
}
// if logon succeeds, create a WindowsIdentity instance
WindowsIdentity winIdentity = new WindowsIdentity(handle);
System.Security.Principal.WindowsIdentity newId = System.Security.Principal.WindowsIdentity.GetCurrent();
// close the open handle to the authenticated account
CloseHandle(handle);
return winIdentity;
}
public void Impersonate()
{
// authenticates the domain user account and begins impersonating it
this.impersonationContext =
this.Logon().Impersonate();
}
public void Undo()
{
// rever back to original security context which was store in the WindowsImpersonationContext instance
this.impersonationContext.Undo();
}
[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);
}
}
Any help would be greatly appreciated.
Thanks Matt
Here is an example of the code I am using:
Impersonator imp = new Impersonator(txtUser.Text,txtDomain.Text,txtPassword.Text);
imp.Impersonate();
FileInfo[] fil = (new DirectoryInfo(")GetFiles();
for(int i = 0 ; i < fil.Length ; i++)
{
lstFiles.Items.Add(fil.Name.ToString());
}
imp.Undo();
NOW HERE IS THE CLASS IMPERSONATOR THAT I DOWNLOADED TO TRY AND USE:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
namespace Mariner.WebParts.Security
{
/// <summary>
///Jay Nathan - MARINER, LLC. - ///Impersonator class allows client code to impersonate another domain user account by handling underlying account authentication and security context manipulation
/// </summary>
public class Impersonator
{
// private members for holding domain user account
credentials
private string username = String.Empty;
private string password = String.Empty;
private string domain = String.Empty;
// this will hold the security context for reverting back to the client after impersonation operations are complete
private WindowsImpersonationContext impersonationContext = null;
// disable instantiation via default constructor
private Impersonator()
{}
public Impersonator(string username, string domain, string password)
{
// set the properties used for domain user account
this.username = username;
this.domain = domain;
this.password = password;
}
private WindowsIdentity Logon()
{
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
// attempt to authenticate domain user account
bool logonSucceeded = LogonUser(this.username, this.domain, this.password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
if(!logonSucceeded)
{
// if the logon failed, get the error code and throw an exception
int errorCode = Marshal.GetLastWin32Error();
throw new Exception("User logon failed. Error Number: " + errorCode);
}
// if logon succeeds, create a WindowsIdentity instance
WindowsIdentity winIdentity = new WindowsIdentity(handle);
System.Security.Principal.WindowsIdentity newId = System.Security.Principal.WindowsIdentity.GetCurrent();
// close the open handle to the authenticated account
CloseHandle(handle);
return winIdentity;
}
public void Impersonate()
{
// authenticates the domain user account and begins impersonating it
this.impersonationContext =
this.Logon().Impersonate();
}
public void Undo()
{
// rever back to original security context which was store in the WindowsImpersonationContext instance
this.impersonationContext.Undo();
}
[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);
}
}
Any help would be greatly appreciated.
Thanks Matt