Impersonation

G

Guest

My goal is to upload/download files to a shared folder. I have been granted
a "generic" account to be used for this purpose. I have designed a page
which will do this download. My quandry is when the user access the page, I
retrieve their "User.Identity" and log activity to that user on this screen
to the Database. If I used impersonation in web config file, then I really
loose the true user's identify and can not really log there usage into the
system because the "generic" id is substituted.

I have been reading that I can use Impersonation via code for a portion of
the page. This looks like a solution to my problem but I seem to be limited
to the account that is actually using the application. Is there a way for me
to create a WindowsIdentity object with my generic account? Do you have an
example?
 
G

Guest

Here's what you need:

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
/// <summary>
/// Summary description for ImpersonateUser.
/// </summary>
public class ImpersonateUser
{

[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);

// constants used by LogonUser() method
private const int LOGON32_LOGON_NETWORK = 3;
private const int LOGON32_PROVIDER_DEFAULT = 0;

private WindowsImpersonationContext wic = null;
private WindowsIdentity currentIdentity = null;

public ImpersonateUser(string login, string password, string domain)
{
// Get current Identity
currentIdentity = WindowsIdentity.GetCurrent();
// 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);
wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
}

public void Undo()
{
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
}

}

}
 
G

Guest

Did I not read that this will only work on Windows XP and will not work on
Windows 2000?....
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfSystemSecurityPrincipalWindowsIdentityClassImpersonateTopic.htm

Kevin Schlegelmilch said:
Here's what you need:

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
/// <summary>
/// Summary description for ImpersonateUser.
/// </summary>
public class ImpersonateUser
{

[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);

// constants used by LogonUser() method
private const int LOGON32_LOGON_NETWORK = 3;
private const int LOGON32_PROVIDER_DEFAULT = 0;

private WindowsImpersonationContext wic = null;
private WindowsIdentity currentIdentity = null;

public ImpersonateUser(string login, string password, string domain)
{
// Get current Identity
currentIdentity = WindowsIdentity.GetCurrent();
// 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);
wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
}

public void Undo()
{
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
}

}

}


Jim Heavey said:
My goal is to upload/download files to a shared folder. I have been granted
a "generic" account to be used for this purpose. I have designed a page
which will do this download. My quandry is when the user access the page, I
retrieve their "User.Identity" and log activity to that user on this screen
to the Database. If I used impersonation in web config file, then I really
loose the true user's identify and can not really log there usage into the
system because the "generic" id is substituted.

I have been reading that I can use Impersonation via code for a portion of
the page. This looks like a solution to my problem but I seem to be limited
to the account that is actually using the application. Is there a way for me
to create a WindowsIdentity object with my generic account? Do you have an
example?
 
G

Guest

I've run it on Windows 2000 and Windows 2003 and both worked for me ...

Jim Heavey said:
Did I not read that this will only work on Windows XP and will not work on
Windows 2000?....
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfSystemSecurityPrincipalWindowsIdentityClassImpersonateTopic.htm

Kevin Schlegelmilch said:
Here's what you need:

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
/// <summary>
/// Summary description for ImpersonateUser.
/// </summary>
public class ImpersonateUser
{

[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);

// constants used by LogonUser() method
private const int LOGON32_LOGON_NETWORK = 3;
private const int LOGON32_PROVIDER_DEFAULT = 0;

private WindowsImpersonationContext wic = null;
private WindowsIdentity currentIdentity = null;

public ImpersonateUser(string login, string password, string domain)
{
// Get current Identity
currentIdentity = WindowsIdentity.GetCurrent();
// 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);
wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
}

public void Undo()
{
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
}

}

}


Jim Heavey said:
My goal is to upload/download files to a shared folder. I have been granted
a "generic" account to be used for this purpose. I have designed a page
which will do this download. My quandry is when the user access the page, I
retrieve their "User.Identity" and log activity to that user on this screen
to the Database. If I used impersonation in web config file, then I really
loose the true user's identify and can not really log there usage into the
system because the "generic" id is substituted.

I have been reading that I can use Impersonation via code for a portion of
the page. This looks like a solution to my problem but I seem to be limited
to the account that is actually using the application. Is there a way for me
to create a WindowsIdentity object with my generic account? Do you have an
example?
 
P

Paul Clement

¤ My goal is to upload/download files to a shared folder. I have been granted
¤ a "generic" account to be used for this purpose. I have designed a page
¤ which will do this download. My quandry is when the user access the page, I
¤ retrieve their "User.Identity" and log activity to that user on this screen
¤ to the Database. If I used impersonation in web config file, then I really
¤ loose the true user's identify and can not really log there usage into the
¤ system because the "generic" id is substituted.
¤

Actually, it's just the opposite. If you implement impersonation the thread operates under the
credentials of the authenticated user (via NTLM), not ASPNET (or NetworkService).


Paul
~~~~
Microsoft MVP (Visual Basic)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top