Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Using programmatic Impersonation from an ASP.NET Page


:P
On this page:

Several times I've heard the following question asked:

I have an ASP.NET application and I need access to network resources that my account running ASP.NET  does not have. How can I change the permissions at runtime without setting up Impersonation or using a high privilige account for my ASP.NET user account?

In short, how can you raise permissions of an ASP.NET request at runtime to perform some task that requires rights that the standard account ASP.NET runs under cannot handle?

To accomplish this you can use various system API calls (LogonUser, ImpersonateLoggedOnUser and RevertToSelf) to change the currently active account ASP.NET runs under. This would be  Environment.UserName as opposed to Page.User. Environment.UserName returns the threads currently logged on user. Page.User returns the name that ASP.NET verifies through Authentication and this user in most cases is independent of the Windows logon that is running the current thread. For anonymous requests Page.User is blank, while Environment.User will be NETWORK SERVICE (or ASPNET on IIS5).

The only time when Page.User reflects Environment.User is when Impersonation is enabled in which case the ASP.NET automatically changes the impersonation on the underlying ASP.NET thread to match of who's logged on. For anonymous users this will be the IUSR_ account or if logged on the user who logged on.

With the API calls mentioned above you can change the thread's security environment. The idea is, you can log on as a user, change the impersonation to that environment, do your thing then revert back. Let's look at how to do this first before going over some caveats. Given that you have rights to use PInvoke calls to make these API calls (NETWORK SERVICE generally does have these rights) the following code can be used to accomplish this:

using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Runtime.InteropServices; using System.Text; namespace Westwind.WebStore.Demos { /// <summary> /// Summary description for Test. /// </summary> public class Test : System.Web.UI.Page { const int LOGON32_LOGON_INTERACTIVE = 2; const int LOGON32_LOGON_NETWORK = 3; const int LOGON32_LOGON_BATCH = 4; const int LOGON32_LOGON_SERVICE = 5; const int LOGON32_LOGON_UNLOCK = 7; const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; const int LOGON32_LOGON_NEW_CREDENTIALS = 9; const int LOGON32_PROVIDER_DEFAULT = 0; [DllImport("advapi32.dll", SetLastError=true)] public static extern int LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken ); [DllImport("advapi32.dll", SetLastError=true)] public static extern int ImpersonateLoggedOnUser( IntPtr hToken ); [DllImport("advapi32.dll", SetLastError=true)] static extern int RevertToSelf(); [DllImport("kernel32.dll", SetLastError=true)] static extern int CloseHandle(IntPtr hObject); private void Page_Load(object sender, System.EventArgs e) { Response.Write( Environment.UserName + "<hr>"); IntPtr lnToken; int TResult = LogonUser("ricks",".","supersecret",
LOGON32_LOGON_NETWORK,LOGON32_PROVIDER_DEFAULT,
out lnToken); if ( TResult > 0 ) { ImpersonateLoggedOnUser(lnToken); StringBuilder sb = new StringBuilder(80,80); uint Size = 79; Response.Write( Environment.UserName + " - " +
this.User.Identity.Name + "<hr>"); RevertToSelf(); Response.Write("<hr>" + Environment.UserName); CloseHandle(lnToken); } else { Response.Write("Not logged on: " + Environment.UserName); } return;
}
}

To use this code change the username and password in the call to LogonUser to a valid local or domain account (see MSDN Docs for exact syntax to use for domain accounts and machine names).

When you run this code you should see:

NETWORK SERVICE
ricks
NETWORK SERVICE

which corresponds to the original account the page is running under, the Impersonation that I applied, and then after I reverted back to the original account.

Note that you should make sure to close the Token handle returned after you are done with your request, preferrably in a Finally section so you don't leak handles.

Actually you don't have to revert back - ASP.NET assigns security to the ASP.NET thread before your request starts, so Revert is not really required.

Caveats

Now is this a good idea to do this in your code? Not really, because it's obviously a potential security risk. There are two things that are a problem here.

First you need to run under an account that has rights to make PInvoke calls which is by no means guaranteed. Many multi-hosted ISPs will set up very low right accounts for their sites so that you may not be able to actually perform these tasks. OTOH, it's unlikely that in an ISP scenario you would actually need access to additional resources that require impersonation.

Second and maybe more importantly using LogonUser requires that you use a password and that password has to come from somewhere. This means somewhere in your system you have to store this password and retrieve that password which can be compromised and then potentially be used to further penetrate security. A fairly far fetched hack scenario that would require somebody pretty damn familiar with your architecture, but still a threat.

You can also impersonation system accounts like SYSTEM and NETWORK SERVICE which don't require passwords (pass "" for the password), but most likely these accounts are not what you need to get your job done - for example access another machine on the network.

Alternatives

Ultimately the solution to this problem is to set up your ASP.NET application with the right account with the exact rights it needs. While I think security is important it's always been my feeling that if someone can penetrate your network and compromise ASP.NET pages - they're in too far already to not be able to do the rest (like changing web.config and stepping down security), so I am usually not opposed to running ASP.NET in slightly elevated security modes to match my needs.

Another option for those one off requests is to use Impersonation and Windows Security in a separate directory. I do this in several of my applications where several admin requests require elevated rights. These pages sit off in a seperate directory with anonymous access off and Impersonation enabled in a separate web.config (or a Location section in the main web.config).

An example of this is my Configuration class manager which has the capability to write Config changes back into Web.Config. I don't want to give NETWORK SERVICE rights to write any files in my main application directory, so I have my Configuration page off in an Admin directory. Admin requires Windows Security and then uses Impersonation, which means it runs under my Admin account on the server once I've logged in with my username and password.

<location path="admin"> <system.web> <identity impersonate="true" /> <!-- WS: Allow only Authenticated users --> <authorization> <!-- allow users="*"/ --> <deny users="?" /> </authorization> </system.web> </location>

I can set this up in a couple of ways. Here I do it all through ASP.NET's impersonation and security settings which deny access to non-authenticated users to these Admin pages. I could also set this up with directory security on the Admin directory and simply remove IUSR_ to achieve the same effect although I would still need the impersonate setting in web.config.

This works well as long as the requests in question can be easily isolated and users are that are accessing these requests indeed can authenticate, which is not always the case.

Use with care... and don't impersonate GrandMa - it ain't nice!


The Voices of Reason


 

CodeBetter.Com Link Blog
February 25, 2005

# Using programmatic Impersonation from an ASP.NET Page


banti
February 28, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

This article is very useful to me, i want to know how can i change impersonate for the whole applciation programtically.

My requirement is that once a user is logged in, he requests some pages and then he want to switch as another user, and will request more pages.

i am giving a seperate form to get user details (username, password, domain) to log in as a different user & i am changing impersonate as per your code. but this impersonate is limilted to that page only, when i am checking the same user on different page, its again givin me the origional impersonate and not the changed one.

thanks,
Banti

Rick Strahl
February 28, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

You can't persist any impersonation across pages because this is a Web application and each request must re-establish its state. Impersonation is handled by IIS and it will assign its default impersonation on every hit. So if you need custom impersonation you need to manage that in your own code using the approach above ON EVERY REQUEST!

Greg
March 28, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

This is an excellent article. I have a question about deployment though. I have setup this and it works fine in my development environment (laptop). I deployed it to our win2k server and it is acting like the username/password/domain is incorrect. I know the information is correct. Are there any additional setups that need to be done say to the local policy or anything like that? Thanks.

Greg

Sandu
April 14, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Is it posible to use this code for maintain this impersonation during the whole session ?

Rick Strahl
April 14, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

No. ASP.NET assigns impersonation at the beginning of every request on the inbound thread. Since you can do this on every request this shouldn't be problem though.

Kevin
April 20, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I need to give the ASPNET account access rights to network resources. Can someone direct me to using Impersonation...? Is this the best way to do this or can I change ASPNET users rights directly? Also, does ASPNET user automatically have rights to running custom made DLLs?

Clear-RCIC
April 26, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Good article. I wrote some similar code about a year ago. I had to call Microsoft to get the details of what this article explains. Everything you've written appears to be accurate. However, to solve the problem of persisting impersonation between pages I checked group membership after a form logon. If they were a member of any windows groups that I was filtering, I set a session variable Session("IsInThisGroup")=True. This allowed me present dynamic links and content based on who had logged on.

suman
April 27, 2005

# re: Using programmatic Impersonation from an ASP.NET Page


i badly need help. pls find the
code below
here i am passing the username and password to the network credential object inorder to authenticate the proxyserver. Instead I want to authenticate the proxy server using the currently logged in windows user. Do u have any clue abt how to do this ? pls help

Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create("http://www.testsite.com"), HttpWebRequest)
Dim myProxy As New WebProxy("http://isa:80", True)
Dim x As New NetworkCredential

myProxy.Credentials = New NetworkCredential("myusername", "mypassword", "mydomain")
myHttpWebRequest.Proxy = myProxy
Dim myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
Dim receiveStream As Stream = myHttpWebResponse.GetResponseStream()
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Dim readStream As New StreamReader(receiveStream, encode)
Dim read(256) As [Char]
Dim count As Integer = readStream.Read(read, 0, 256)

Rick Strahl's WebLog
May 18, 2005

# Understanding ASP.NET Impersonation Security

Understanding how ASP.NET's internal security works is important if your application needs to access resources on the local machine. Specifically it's important to know exactly which account your ASP.NET application is running under. This entry reviews different ways of how this account is affected by different versions of Windows, and ASP.NET configuration.

stardawg
May 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

This works fine for accessing local files. However, when I try to access a file share on a win2k box from an asp .net page on a win xp box it breaks?

Please advise.

Rick Strahl
May 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

It should work as long as the account you are using has the proper network rights.

stardawg
May 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I am trying to copy a local file to a network share. The impersonated user has access to the share, but I get this error

An unhandled exception of type 'System.Web.Services.Protocols.SoapException' occurred in system.web.services.dll

Additional information: Server was unable to process request. --> Access to the path &quot;\\serverName\BIER\BIER_PrintService\Queues\HTML\TEST.html&quot; is denied.


here's my code:
WindowsImpersonationContext impContext = null;
try
{
impContext = NetworkSecurity.ImpersonateUser(
"DOMAIN",
"user",
"pwd",
LogonType.LOGON32_LOGON_NETWORK,
LogonProvider.LOGON32_PROVIDER_DEFAULT);

if (null != impContext)
{
try
{
File.Copy(FILE_NAME,REMOTE_FILE_NAME);
} //end try
catch (Exception ex)
{
//Response.Write(ex.Message);
throw(ex);
} //end try
finally
{
// Finally we have to revert the impersonation.
impContext.Undo();
File.Delete(FILE_NAME);
} //end finally

Rick Strahl
May 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Local network shares won't work unless you defined the share in your app. The share exists in the interactive session (the desktop), but not in the session that is running ASP.NET (NETWORK SERVICE). You need to use UNCs or explicitly create the share from your app (in Application_Start or a static constructor maybe).

stardawg
May 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Sorry for the confusion, I am using UNCs:

string REMOTE_FILE_NAME = @"\\remoteServer\BIER\BIER_PrintService\Queues\HTML\TEST.html";
string FILE_NAME = @"\\localServer\images\test.html";

No problem accessing UNC on the local server (XP development box), but I get the access denied error when trying to access the remote server(win 2k server).

BTW
Thanks for the help and the quick responses :)

Geof
June 01, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Accessing network resources using impersonation is much more difficult (well, it's not hard to do, but it's tricky to troubleshoot). This would include SQL Server databases on a different machines, as well as file shares on other machines.

To do this requires a technique called "delegation", which is like impersonation except that the ASP.NET process now has to convince a -second- machine to act using the user's account.

You can find information on this with Google "trust for delegation" or similar. Not all accounts are allowed to delegate, and some accounts can't be delegated.

The reason for this is that an evil web designer could create a web page using impersonation that checked to see if the user happened to be a superadmin, then use that user's account to grant the web designer superadmin priveleges, and the admin would never be the wiser.

stardawg
June 03, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Thanks for the info!

Sathya
June 23, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

This is indeed great article.
Rick, Is there anyway I can automatically take user name who logged in to the system, This way I do not have to supply password. And also I do not need to supply the password whenever I change my AD password.

tman
July 12, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Ok I'm not sure why this is not working in the way I need it to. I used this pretty much exactly as is then launched a command prompt and did a whoami as follows:

ImpersonateLoggedOnUser(lnToken); ProcessStartInfo psInfo = new ProcessStartInfo("cmd.exe");
psInfo.UseShellExecute = false; psInfo.RedirectStandardOutput = true;
psInfo.RedirectStandardInput = true;
psInfo.RedirectStandardError = true;
Process pBatch = Process.Start(psInfo);
StreamReader srOutput = pBatch.StandardOutput;
StreamWriter sWriter = pBatch.StandardInput;
sWriter.WriteLine(@"date /t"); sWriter.WriteLine(@"whoami");

Yet the output of the whoami still shows Network Service as the user. I need this command prompt to be running as the account i'm attempting to impersonate. Any ideas?

Rick Strahl
July 12, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

The logon is essentially a new session - you won't see this outside of the running process.

tman
July 12, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

In that case how would one launch a command prompt as user XYZ from an asp.net app, where a whoami command would correspond to the specified user. I've tried several methods for this with no luck, any ideas?

tman
July 13, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I was under the assumption that if i was impersonating an account and launched a process that the process would be running under that impersonation account. Yet this is not the case it still reverts back to Network Service, I really need a solution to this. Anyone worked through this type of thing before?

aone999
July 15, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Iam facing a related problem.

In an ASP.Net page, iam instantiating a COM component. The COM component reads info from the HKCU reg key and populates it's properties.

Now, since ASPNET account doesnot have any keys under HKCU, this COM component fails. So, I decided to use impersonation.

I impersonated the ASPNET account to a known windows account (in web.config). However, the COM component still fails.

Interestingly, if i make the impersonation in machine.config, the COM component works perfectly, using the profile of the impersonated account. But i don't want to do this, as it is a global change and affects all the web applications on this machine.

Any suggessions?

Rick Strahl
July 15, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

You can't overrride the Windows account used for the process in web.config because - it can only be set in machine.config. In fact, you should get a failure if you do. You CAN do this on Windows 2003 Server by configuringing the Application Pool to run under a specific account. Win3k ignores this setting and uses the Application Pools identity.




tman
July 19, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Creating a new application pool and using the configurable identity setting to specify the particular user worked like a champ. The only additional thing that was needed was adding that user to the IIS_WPG group. Thanks.

Greg
July 21, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

OK - my situation is slightly different. I need to copy files to the local machine, then to a machine on the local network then to several servers on a different domain completely (a file sprayer of sorts). I can copy to the local machine and local network but not to the outside domain. I can use windows explorer to go directly to these outside domain boxes, i can ping them and use DOS to xcopy files directly to them. With C#/Asp.net I get permissions errors. Is there a way to impersonate a user on the outside domain since i have the user, pass, and domain credentials?

Dean Dalby
August 02, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

To be able to login to the SQL server we explicitly call the LogonUser function from the advapi32.dll then open a SQL Connection using the Integrated Security=true property. When you look at SQL Profiler it seems that there is two logon calls made when the connection is opened. One for the ASP.NET machine account and one for the user that we impersonated using the LogonUser function. Does anyone know why this happens? And how to avoid it?

Any additional information that may help explain the two logon calls would be much appreciated.

Thanks in advanced
Dean Dalby

bala
August 27, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Hi

I have an aspx page with download button on my server. When the user clicks that download button, I am trying to download the file (PDF) from my network machine which is under same domain. I am getting this attached error message. I have given all the permission to folder which all the PDF files stroed . I try to ImpersonateUser that user account, that part working fine. after the impersonate, its giving the login failure problem.

Any idea to resolve this.

Here is the code which i am using for downloading the file.


Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim path1 As String = "\\machine02\temp\test.pdf"
Dim name As String = Path.GetFileName(path1)

Dim ext As String = Path.GetExtension(path1)
Dim type As String = ""
If Not (ext Is Nothing) Then
Select Case ext.ToLower
Case ".htm", ".html"
type = "text/HTML"
' break
Case ".txt"
type = "text/plain"
' break
Case ".doc", ".rtf"
type = "Application/msword"
' break
Case ".pdf"
type = "Application/pdf"
End Select
End If
'If forceDownload Then
Response.AppendHeader("content-disposition", "attachment; filename = " + name)
'End If
If Not (type = "") Then
Response.ContentType = type
End If
Response.WriteFile(path1)
Response.End()
End Sub

Thanks
Bala

Wei
August 31, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I tried using this impersonating method in a win app as well as a asp.net app with no luck in accessing the network share folder. Though the impersonation worked perfectly but when accessing the fold I still get "incorrect password" error message. But if I map to the folder using the same credential I can access the files using UNC path. Any idea why ?

Mahendra
October 13, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

i try to read log file from remote computer. i get a Access Denied error. but logfile folder having all the privillages. and i am also log as an administrator

here is my code

int TResult = LogonUser("administrator", "domain", "pwd", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, out lnToken);
if (TResult > 0)
{
ImpersonateLoggedOnUser(lnToken);
StringBuilder sb = new StringBuilder(80, 80);
DirectoryEntry root = new DirectoryEntry("IIS://server/W3SVC","administrator","domain","pwd",AuthenticationTypes.Secure);
foreach (DirectoryEntry ent in root.Children)
{
if (ent.SchemaClassName == "IIsWebServer")
{
Response.Write(ent.Properties["ServerComment"].Value.ToString());
}
}
RevertToSelf();
Response.Write("<hr>" + Environment.UserName + " - " + this.User.Identity.Name + "<hr>");
CloseHandle(lnToken);
}
else
{
Response.Write("Not logged on: " + Environment.UserName);
}
return;

Fi
October 18, 2005

# Using programmatic Impersonation fo accessing LAN web application

Hi, can anyone help me in this regard. I programmatically impersonnated a user on my network, but when i tried to access the web application on my LAN a pop-up window comes up asking to give username password and domain .
My brief code is below,

WindowsImpersonationContext wic = CreateIdentity(User_Alias, Domain, Password).Impersonate();

webBrowser1.Navigate("http://machineName/app");

wic.Undo();


I don't want this window to pop-up , and access the web application by the impersonated user. Plz.Help



Achutha Sundar
October 21, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I am trying to run exe from ASP.Net through process.start. It works on my laptop with XP but not on windows server 2003 SP1 with Sharepoint. As you have suggested I have identity impersonate="true" in my web.config file. I also modified machine.config file ProcessModel username="SYSTEM" on the windows 2003 server. Can anyone help?


Shane Hale MCSE
October 27, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Hello,

You guys are all working at a much higher level than me, but I was wondering if one of you could help me out with a sample peice of code to get me on my way.

I dont wish to elevate priveledge or impersonate anything. I work for a charter school as a administrator and we are filtering student web access using IAS. What we want to do is give the kids a little something to think about when they attempt to access filtered content and are redirected to the access denied page.

We want to put the logged on username and pcname & ip in message returned to them in the page, letting them know the attempt and thier username was logged. I thought I could do this easily just doing:
<%
Response.Write Request.ServerVariables("REMOTE_HOST")
Response.Write Request.ServerVariables("REMOTE_USER")
Response.Write Request.ServerVariables("REMOTE_ADDR")
Response.Write Request.ServerVariables("LOGON_USER")
%>

But alas even though I am trying to get the info from machines on a LAN that I administer, the only info returned was the IP.

I realize this is a security measure with modern servers to protect our info on the internet but on the LAN we (administraors) should have authority.

At any rate, the subject of this thread seems like it could be used (or something simular) to get the info I want to return. However I only have a basic understanding of ASP and no real ASP.NET experience. Any help or a referral in the right direction would be greatly appreciated.

Shane Hale MCSE

Rick Strahl
October 27, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

HTTP provides only access to a few things, and those things won't stop a hacker since the browser sends these things and they can be overridden completely by a custom HTTP client.

You can do DNS lookups of IP Addresses to get machine or server names if they are registered in DNS.

Shane Hale MCSE
October 28, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Thanks for the tip. The machines are in fact registered in DNS and the users are logged into the AD. Do you have any suggestions where I could go to find an example of how to do what you are suggesting? Thanks for your response.

Arlean
November 09, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Hi,

Even I put <identity impersonate="true" userName="User" password="password"/> in web.config, when calling a batch file from an asp.net page, the batch file is still run under ASPNET account. Actually before calling batch, I checked the environment.username on .net page, it is ¡°user¡± not ¡°ASPNET¡±.

The test batch file:

echo %time% >test.txt

echo %username% >> test.txt

In test.txt the username is always ASPNET.

Anybody knows if there is a way to run batch file under a user account other than ASPNET?

I'm thinking to call "CMD.EXE" then run "runas" command to change user. However, runas will prompt to input user password. Can we start an interactive mode from asp.net?

Thanks in advance for any help,

Arlean


Jon C
November 11, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Great work on this article. It answered my "impersonation across the session" question.

But I am not sure how I can use impersonation to access NTFS protected files like .gif and .jpg, resources that cannot be impersonated. But need impersonation to access them.

Can you point me in another direction?!

Thank you.

Gosha Kuciy
November 13, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

Hi! I found your site <A HREF="http://google.com">here">http://google.com">here
</A> [ http://google.com ]
When you look at SQL Profiler it seems that there is two logon calls made when the connection is opened. One for the ASP.NET machine account and one for the user that we impersonated using the LogonUser function. Does anyone know why this happens? And how to avoid it?



stuki
November 15, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

hi,
I'm using impersonation because i've had a problem with creating files on localhost. On the other side I have peace of code which creates win process, starts it and stops it. When I use impersonation, that code doesnt work (I can not start or stop the process). When I shut impersonation, I have problem with accessing the files (Access is denied)
Anyone can help?
Thanks in advance

Benihana
December 13, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

I'm getting back:
Page User ID is Authenticated: True
Page User ID Authentication Type: NTLM
Page User Id Name: Domain\Username
Environment Username: SYSTEM
Environment User Domain Name: NT AUTHORITY

Strange, I don't see NETWORK SERVICE anywhere. I'm getting this info by: Page.User.Identity.Name.ToString & "<BR>Environment Username: " & Environment.UserName.ToString & "<br>Environment User Domain Name: " & Environment.UserDomainName.ToString etc.

It scans the local server fine, but any other server says "Access Denied". I tried everything. Hope you can help Rick!

Rick Strahl
December 13, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

What version of IIS are you running? If you're running IIS 5 then your underlying system account is SYSTEM and it's not configurable.

In IIS 6 the OS account is configurable - and if you're running IIS 6 you might have your APplication Pool set to the Local System impersonation.

kenneth Roach
December 27, 2005

# re: Using programmatic Impersonation from an ASP.NET Page

When I run the following code I only get the machiene drives not the netowork mapped drives
could anyone help??



IntPtr lnToken;
int TResult = LogonUser("username","domain","Password",
LOGON32_LOGON_NETWORK,LOGON32_PROVIDER_DEFAULT,
out lnToken);
if ( TResult > 0 )
{
ImpersonateLoggedOnUser(lnToken);
StringBuilder sb = new StringBuilder(80,80);

uint Size = 79;
Response.Write( Environment.UserName + " - " + this.User.Identity.Name + "<hr>");
string[] drives = Environment.GetLogicalDrives();
// Response.write("Available drives:");
foreach(string drive in drives)
Response.Write(drive);
// Console.ReadLine();


RevertToSelf();
Response.Write("<hr>" + Environment.UserName);

CloseHandle(lnToken);
}
else
{
Response.Write("Not logged on: " + Environment.UserName);
}

ClickOk
January 03, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi

I'm doing one file manager in ASP.Net. I put permissions to read/write some folder. I can create files, but I can't delete! I can resolve this with this web.config aproach?

TomekR
January 10, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi !

Anyone has idea, why above code doesn't want to work on W2K and IIS5, but deployed on W2K3 & IIS6 works exactly as described ?
I mean, on IIS5 LogonUser returns 0.

I both cases the same user/passw is configured and defined to be used. Also exactly the same web.config is used.

bit
January 12, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

good stuff

TomekR
January 12, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

The reason why the code above won't work on W2K (IIS5 has nothing to do wit it) is the fact, that on W2K system process calling LogonUser function has to have special right i.e. SE_TCB_NAME privilege.
To make ASPNET or IUSR_xxx user has this right, one need to:
1.
Open "Administrative Tools | Local Security Policy" and then double-click on "Local Policies".
2.
Open "User Rights Assignment" and then double-click on "Act as Part of the Operating System".

Add the wanted account to do list.

Baskaran Ammamuthan
January 20, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

I was trying to create a file in network shared folder using filestream object. I followed all your steps. It is changing enviromnent user name in the order ASP.NET, myusername, ASP.NET. I am getting error access denied. My user account has privillage to create/modify privillage.

bestcomy
January 25, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

maybe this is a right article for all of you
http://www.codeproject.com/csharp/ZetaImpersonator.asp

NOTE: you should add domain user as a local administrator if you want to copy a local file to a network shared folder.

Abs
March 01, 2006

# Read and display the current logged on username

Hi,

I hope someone can help. I don't need to use pass through to authenticate my application. I just want to be able to save the username into a variable for later use, for example when a user submits a form, I want to record the username who made the change. How can I do thi?

Aaron Ramirez
March 14, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

All good and fine, one thing that I saw reading the posts, is that the pinvokes won't work on win2000 due to security restrictions. Also what some of you may have missed in attempting to get the impersonation to take place in a web app, is in the web.config you must make sure that <identity impersonate="false"/> or you will get access denied error message. Also impersonating a user does not change the account under which a asp.net page/request runs, Page.User is readonly and is locked into the user that is currently logged into windows if you are using windows auth. There is good P&P article @ MSDN to explain all the different combos of auth and impersonation(and security in general): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetAP05.asp

Agnel CJ Kurian
March 21, 2006

# Accessing Shared Folders in ASP.NET


ms hater
April 25, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Fuckin' shit Microshit Impersonate Fuck bullshit is wasting my fucking time.

mahesh
April 26, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

I implemented the above impersonation by using debugger i was able to trace the out put. Actually the impersonation is done but i was not able to access the files on the network machine.
The permissions are assigned the user through which impersonation is done.

Although the current thread is impersonated it is throwing access denied exception what may be the problem. on the network machine i assigned full rights to the user.

Fried Egg
May 05, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Does anyone have a VB version of this code?

paresh
May 25, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

How can I copy to a machine in a different domain?

If it is in the same machine or same domain it works fine but fails when the domain is different.

Any thoughts?

TIA,
Paresh

Rick Strahl
May 25, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

You can't unless the account running IIS has permissions on that remote machine. You need to create an account on that domain that matches or otherwise adjust the security so that the ASP.NET machine/account has access.

If you can't you're SOL.

Simply Si
June 12, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

This is a useful article although i was wondering if you could help me further. I have a web application of which i need to determine the Windows Logon for the current user. The web application web.config has the following setting:
<authentication mode="Windows" />
<authorization>
<allow users="*" />
</authorization>
The web server is running IIS and has the following settings. Anonymous Access is enabled and Integrated Windows Authentication is disabled.
What i need to return is the domain/username, so it returns the actual user like john.smith of mydomain/js.
Initially i have created a seperate directory in the solution with an aspx page an a seperate web.config with <identity impersonate="true"/>. Will this give me what i am looking for?

Salah
July 19, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Why i got blank page when running the code of this article?

k03123
August 10, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi Rick,

How does firewall affect impersonation? well, i have written a program which authenticates a user using ldap and stores the user password in session variable. for any action required - add/edit/delete of files, i am supplying the user name, domain and saved password. am able to access network resources as well but when i moved the program to production server, which is apparently outside the firewall, it can't impersonate. network resources are inside the firewall.

is it possible at all to do impersonation between firewall? maybe by opening ports? any help appreciated.

Rick Strahl
August 10, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

It depends on the firewall. If the firewall strips authentication information then no it's not going to work. However, most proxy type firewalls shouldn't strip this information and so request should continue to work.

k03123
August 10, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Thanx Rick.

I appreciate your response. I will have a chat with system administrator and see how it goes.

Vazeem
August 13, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi Rick,
I have a situation here.
My Web applciation is running on two servers parallel for the purpose of NLB. Application needs to read/write files from local folders. since I cant put the files on both servers(it will replicate the data), I decided to create folders in my primary server and create a Network map drive on both servers with the same drive letter pointing to the folders in the primary server. Since NLB server will redirect the request to any of the two server, this is the only way i found. But now problem is ASP.NET is not able find the network drive, it throws the exception that Directory not found.
If I use IP Address instead of Network drive, it works fine. But I cant use it the reasone being, in case of any hardware failure switching the IP address is difficult....

Forgot to mention, my application is only an "Intranet" application.
Please suggest me any alternative...

cbv
August 14, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi Rick,

What is the differance between Impersonation and changing the "userName in ProcessModel" tag? Effectively, whether we change the useName in ProcessModel, or make the application Impersonatate, we are achieving the same thing right?

mk
November 01, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

i changed the machine.config file which is at C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG and in the processModel tag changed the username to "system" and password to "AutoGenerate"..as a result of this the ASP.NET process does run as a system process...that is if i put these test lines in the code..

string usr1=System.Security.Principal.WindowsIdentity.GetCurrent().Name;
string usr2 = System.Environment.UserName;

as a result of this
usr1=@"NT AUTHORITY\SYSTEM"
and usr2="SYSTEM"

But,still the ASP.NET code (C# code behind)doesnt seem to have all the privelidges ..for eg..when i do

System.Collections.IDictionary all_vars=System.Environment.GetEnvironmentVariables();

then,the ASP.NET code doesnt show the environment variables which i have manually created beforehand,while a simple C# code shows all the environment variables..similarly there are many cases where ASP.NET cant perform the expected task whereas a simple C# script does it....

any solutions to this???

Andrew
November 07, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

We use identity impersonate in our web.config to access a file share via UNC - Which works fine if the share is in the same domain.

However, we want to access a share in a different domain, but when we specify an account in the local domain that matches an account and password in the remote domain, we still get an invalid path or file name from System.Data.OleDb.OleDbException (we're trying to access a data source on the remote domain)

I noticed you mentioned that it may be possible to do that programatically if the accounts match ID and password... But is it possible to do it in the web.config, as we are trying to do..? Since we cannot modify the source code of the application... Our only option is in the web.config.

We've also tried using a local account (instead of a domain account) that matches the remote domain account a password with similar (failed) results.

Any thoughts or suggestions much appreciated! :)

Rick Strahl
November 07, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Depends on the machine.config configuration. By default the account information is locked down so you can't change it web.config level.

On IIS 6 the machine account is determined by the IIS Application Pool Impersonation, and that can't be overridden as far as I know.

Sumit
November 08, 2006

# How to pass Username and password when accessing Network Folder

hi i am developing a windows service that will pick file from a Network folder so i want how to pass Username and Password in order to access that Folder.

Andrew
November 08, 2006

# re: Using programmatic Impersonation from an ASP.NET Page

Hi Sumit... If you scroll up to the top of this page and read the article... That's pretty much what the article tells you how to do! Since it's basically about impersonating a user.. You'd just impersonate the account that has the rights to that folder. I think it should work for a service just as well. :)

Israel Aéce
January 03, 2007

# Israel Aéce


Security
January 12, 2007

# ASP.NET Forums - writing files


Security
January 16, 2007

# ASP.NET Forums - Programmatic impersonation


Web Forms
January 19, 2007

# ASP.NET Forums - accessing network share using C#


Damian
January 25, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

Can this procedure be implemented to control access to non-asp.net files within the website (i.e... word document, excel files, images)? In other words, can I prevent users from accessing the above files with URLs by using the above procedure?

Thanks,

Damian

Security
February 15, 2007

# ASP.NET Forums - what is Impersonation


Josh
February 27, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

ok; it appeared to work i.e. I could run the code and when viewing the Environment.UserName it was showing the new impersonated username - sweet.

BUT when trying to connect to a remote db using a trusted connection it fails with the error 'NT AUTHORITY\ANONYMOUS LOGON'.

Any ideas?

Getting Started
March 20, 2007

# ASP.NET Forums - credentials and impersonation


Installation and Setup
April 18, 2007

# ASP.NET Forums - Access denied error

# Scott Hanselman's Computer Zen - Avoid using Impersonation in ASP.NET

Scott Hanselman on Programming, User Experience, The Zen of Computers and Life in General

ASP.NET Forums
May 18, 2007

# accessing network share using C# - ASP.NET Forums


ASP.NET Forums
May 22, 2007

# writing files - ASP.NET Forums


ASP.NET Forums
May 23, 2007

# Access denied error - ASP.NET Forums


ASP.NET Forums
June 04, 2007

# Programmatic impersonation - ASP.NET Forums


gazeteler
June 30, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

i try to read log file from remote computer. i get a Access Denied error. but logfile folder having all the privillages. and i am also log as an administrator

here is my code

int TResult = LogonUser("administrator", "domain", "pwd", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, out lnToken);
if (TResult > 0)
{
ImpersonateLoggedOnUser(lnToken);
StringBuilder sb = new StringBuilder(80, 80);
DirectoryEntry root = new DirectoryEntry("IIS://server/W3SVC","administrator","domain","pwd",AuthenticationTypes.Secure);
foreach (DirectoryEntry ent in root.Children)
{
if (ent.SchemaClassName == "IIsWebServer")
{
Response.Write(ent.Properties["ServerComment"].Value.ToString());
}
}
RevertToSelf();
Response.Write("<hr>" + Environment.UserName + " - " + this.User.Identity.Name + "<hr>");
CloseHandle(lnToken);
}
else
{
Response.Write("Not logged on: " + Environment.UserName);
}
return;

ASP.NET Forums
July 05, 2007

# credentials and impersonation - ASP.NET Forums


gino_bili
July 06, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

This is from a comment from 2005 but was not given a response. I am having similar problem. Is there anyway I can automatically take user name who logged in to the system, This way I do not have to supply password?

Striking Knife
July 14, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

Beautiful Article Hats off to you excepting more good articles From U

Twood
September 18, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

This is a great article, unfortunately for me I need it in VB. I converted it, but only ended up with a blank page that won't hit the page_load breakpoint, so I have no idea how much (if any) is getting done.

My entire site uses a web.config with forms based authentication. When I try and specify windows based inside a subfolder, the compiler throws an error. I want to keep everything together in one project, and don't want to have to resort to splitting it into another virtual dir.

Torving
November 18, 2007

# Using Impersonation in an application to verify folder permissions

Thanx for a great article.
In your article you write
"You can also impersonation system accounts like SYSTEM and NETWORK SERVICE which don't require passwords (pass "" for the password), but most likely these accounts are not what you need to get your job done - for example access another machine on the network."

My question to you is, how do i impersonate the built-in account NETWORK SERVICE.

I need to find a way to verify if the built-in system account "NETWORK SERVICE" has read and write rights to a specific folder, and a thought that if I could Impersonate the account then I could perform the nessary file operations as that user and thereby determine if the user has the nessary rights on the folder.

Hope i make sense, and that you can find the time to answer me.

Best Regards

Michael T.

Otto
November 21, 2007

# re: Using programmatic Impersonation from an ASP.NET Page

Rick, how about connecting to a network printer not installed on the IIS server, but just installed on a server on the network or shared by a user's computer?

Great article, thanks so much.

Otto.

Bhushan Danej
March 22, 2008

# re: Using programmatic Impersonation from an ASP.NET Page

Hi there,

The information on this page is brilliant.

I am also facing some IIS account heck, and dying to get it worked with already provided solution.

I have got a Web service, which calls a C++ DLL. C++ DLL calls a COM component, which is on another server.
Now while accessing the COM, I am getting "Access is denied" error. But if I run same C++ code from any development environment ( Not under IIS ) it works.

somewhere in this page, its written that I need to Impersonate ASPNET account. But still after adding impersonate = true in Machine.config and web.config, nothing is working.

It must be a simple configuration somewhere, but not getting proper direction.

Can someone help.

clone dvd
March 23, 2008

# clone dvd

Register SIP phone (DPH- 140S) to Asterisk Make Skype call from internet to SIP phone Make SIP phone call to Skype Register DVG- 6004S to Asterisk Make outgoing calls to PSTN via DVG- 6004S Receive incoming calls from PSTN via DVG- 6004S Make Skype call from internet to PSTN line via DVG- 6004S Connecting DVG- 6004S The router to internet is properly setup and have access to the internet. The router shall also provide DHCP service. The PC with Asterisk and ssgwpe is properly setup and connected to the router. ...

Enigma
March 25, 2008

# re: Using programmatic Impersonation from an ASP.NET Page

Hi All,

I also tried Impersonation with asp.net and it is successful.
now i want to create a file on a network location with the impersonated credentials..I am providing proper UNC path but it cannot read or write to my network share folder. When i try to create a file, its says file \\servername\sharepath\file.doc cannot be created.

Can any one help please. its urgent

Thanks

Tired of Impersonation Mania
April 30, 2008

# re: Using programmatic Impersonation from an ASP.NET Page

@Enigma
Go to this URL buried in the comments: http://corner-house.blogspot.com/2006/03/accessing-shared-folders-in-aspnet.html

I successfully implemented accessing a remote share and my ASP.NET pages are reading/writing files like champs.

You love to shop?
May 19, 2008

# You love to shop?

Check out great daily deals!

free dvd copy
June 29, 2008

# free dvd copy

I have the same problem as Lauretn. I have a USB data cable but I don\'t have its driver, I checked the instructions and I found that it need a driver (SER9PL. INF) and it can be found in the http:// tech. prolific. com. tw/ So I cheched the link but it does not work proparly and face some error in accesing inside this link, and can not find the file. Please direct me to the right link where I can find this file.

decoders for dvd
June 29, 2008

# decoders for dvd

Square Enix’ s“ White Engine,” now renamed the Crystal Tools, has been confirmed for work on platforms of PS3, XBox 360 and PC. Also they did announce that they will be using a dumbed down version of Crystal Tools for the Wii Platform. They also showed a trailer for FFXIII. They displayed some gameplay of the lighting effects and stunningly left everyone with a big WOW. They also attempted to quite the corss platform talk of this release, because at the end of the trailer there was a screen saying“ ...

decrypt dvd movie
June 29, 2008

# decrypt dvd movie

So component A which lives in the dll and namespace Com. Hertkorn. Infrastructure. ComponentA and component B which lives in the dll and namespace Com. Hertkorn. Infrastructure. ComponentB should share types. Ideally their shared types live in a component Com. Hertkorn. Infrastructure. SharedTypes. dll but the root namespace should differ. I would argue the root namespace should be Com. Hertkorn. Infrastructure. That way a subdirectory ComponentA or ComponentB would result in a namespace complementing the...

dvdshrink
June 29, 2008

# dvdshrink

Drivers blow their horns constantly, mostly to alert others that they are passing. A four lane road is treated as though it has 6 lanes, a two lane road like it has 3 or 4. It is not unusual to see drivers barrelling up the road on the wrong side of the street, directly into oncoming traffic. This does not seem to bother the drivers who are faced with a head- on collision… they never slow down, though they may move thier vehicle over 2 or 3 feet to avoid the head on collision at speed.

decrypter for dvd
June 30, 2008

# decrypter for dvd

scan IP address , scan your TCP/ UDP ports , scan several specifically popular TCP/ UDP ports.

how to record from dvd
June 30, 2008

# how to record from dvd

alphabetically. However some of the topics are general such as“ Shutdown problems” while others are very specific such as“ sh31w32. dll.” Once you select a topic you’ ll be shown a variety of resources ranging from Microsoft Knowledge base links to simple fix- it guides. Overall, an excellent trouble- shooting resource.

# best dvd burning software

First real obsessive banging the machine was with Street Fighter 2, watching with rapt attention as the local stoner (our guru) talked me thru the special stances taken to get that perfect with a Ryu or Ken type (see champion and/ or cheater). This was lost on me because I was certainly the E. Honda/ Dhalsim type (see foreigner in a foreign land), and proceeded to lose for the four odd years that my local convience store carried the original edition. I did buy pot from our guru (thus providing his money for...

# www.FreeRegistryCleanerScan.com

Buffer overflow in the Server Service in Microsoft Windows 2000 SP4, XP SP1 and SP2, and Server 2003 SP1 allows remote attackers, including anonymous users, to execute arbitrary code via a crafted RPC message, a different vulnerability than CVE- 2006- 1314.

game coping software
July 10, 2008

# game coping software

More Photos/ Subscribe Via Email Subscribe To ORKUT An Epitome: Linux Rocks by Email/ Special Days An error has occurred; the feed is probably down. Try again later. / Page Content About About Orkut Fedora 8: Guide Orkut Security Orkut Tips & Tricks Pc Basics Social Services Suse 10. 3: Guide Ubuntu 7. 10 Guide/ THE WORLD MP3\'s The World: Global hit- Nigeria Special The World: Global hit- Selim Sesler The World: Global hit- Umm Kulthoum The World: Global hit- Torture Playlist The World: Global hit- The Shams...

i m too dvd ripper
July 10, 2008

# i m too dvd ripper

Browser Speed Your browser uses the Domain Name Server (DNS) you listed in your network settings to resolve common domain names (yadda. com- no“ www”) to IP addresses, the real address of a web site. However, this DNS server may be a few hops away from your location on the Internet. That means it takes a bit more time to reach the site you want to surf than it might take if, say, the IP address was listed somewhere on your machine. That’ s exactly what this tweak does- adds the IP address of your most surfed...

Irene
August 04, 2008

# Impersonation NT AUTHORITY\SYSTEM

Please, help me!
I'm trying to create an exe file using IExpress.
I create .sed file correctly (newsedfile parameter in the sub below), but then my following code (that implements impersonation with user NT AUTHORITY/SYSTEM) throws the error "Access is denied" and I don't undestand why!
Windows 2003R2 SP1 or Windows XP SP3; .net framework 2.0
That's All Folks! Thank you a lot!
Irene

private static void createEXE(string newsedfile)
{
IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);

try
{
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
const int SecurityImpersonation = 2;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser("SYSTEM","NT AUTHORITY","",
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);

if (false == returnValue)
{
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
}

bool retVal = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
if (false == retVal)
{
CloseHandle(tokenHandle);
throw new ApplicationException("Exception thrown in trying to duplicate token.");
}

// The token that is passed to the following constructor must
// be a primary token in order to use it for impersonation.
System.Security.Principal.WindowsIdentity newId = new System.Security.Principal.WindowsIdentity(dupeTokenHandle);
System.Security.Principal.WindowsImpersonationContext impersonatedUser = newId.Impersonate();

System.Diagnostics.Process p = new System.Diagnostics.Process();

// cfr. http://www.microsoft.com/technet/prodtechnol/ie/ieak/techinfo/deploy/60/en/iexpress.mspx?mfr=true
/* p.StartInfo.Domain = @"NT AUTHORITY";
p.StartInfo.UserName = @"SYSTEM";
System.Security.SecureString pwd = new System.Security.SecureString();
foreach (char c in "")
pwd.AppendChar(c);
p.StartInfo.Password = pwd; */
p.StartInfo.FileName = "iexpress.exe";
p.StartInfo.Arguments = "/N /Q " + newsedfile;
p.StartInfo.UseShellExecute = false;
//p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

if (p.Start())
{
p.WaitForExit();
}
else
{
throw new Exception("IExpress has not started");
}
// Stop impersonating the user.
impersonatedUser.Undo();
}
catch (Exception exc)
{
throw exc;
}
finally
{
// Free the tokens.
if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle);
if (dupeTokenHandle != IntPtr.Zero) CloseHandle(dupeTokenHandle);
}
}

nipun
September 09, 2008

# re: Using programmatic Impersonation from an ASP.NET Page

Hey rick
I am developing an application which uses exchange server 2007. I have created a web service on the remote m/c where exchange server is installed and then using command prompt i am running powershell scripts here's code snap
string command = "powershell.exe \"& 'D:\\Documents and Settings\\Administrator\\Desktop\\exchange2007\\test.ps1'\"";
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd","/c "+command);

// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
try
{
proc.Start();
}
catch (Exception ex)
{

}
// Get the output into a string
while (!proc.StandardOutput.EndOfStream)
{
result += proc.StandardOutput.ReadLine();
}
i used your provided code it runs well but when the code tries to run the script it gives the following error
Get-MessageTrackingLog : Failed to connect to the Microsoft Exchange Transport Log Search service on computer "mycompany.mycompanyv2.com". Verify that a valid computer name was used and the Microsoft Exchange Transport Log Search service is started on the target computer. The error message is: Access is denied.At D:\Documents and Settings\Administrator\Desktop\exchange2007\test.ps1:2 char:23+ get-messagetrackinglog <<<< -messagesubject test | export-csv 'D:\Documents and Settings\Administrator\Desktop\exchange2007\Book1.csv'
plz help

Monty
December 22, 2008

# re: Using programmatic Impersonation from an ASP.NET Page

I am trying to delegate a task to run automatically based on script completion of another task, I basically want the machine the task is running on to reboot itself and relaunch the task when it finishes. However since the webserver is running under network service and the domain may have group policy enabled to prevent elevating permissions of network service I am having a real problem getting this to work. I know for sure this is strictly a permissions issue but I am not sure how to launch my sub-process to reboot as an admin user from a web page, I know this is a horrible idea from a security standpoint but this machine is used for nothing else and only serves up results of performance tests to internal staff (which is the task that needs to restart when completed).

would the code here work for this purpose?

Avijit Ghosh Roy
January 14, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

Hi Rick, It is really a great post as always been with you. I need to know if I use your code for temporary impersonation to export a crystal report document to a shared path will there be any extra thing that I need to do? I am using crystal report viewer to show one report and on that page there is a button called “Send”. On clicking the button the report need to be exported to a shared location in “*.pdf” format. When I am using this piece of code to run the app, it is asking for my credentials to open the crystal report viewer and then it is not opening the report.

vishwanath
February 10, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

HI,

I am using word template automation using c# and i dont want to use username and password in the web.config and when i user username and password the application running fine, please tell me some solution so that i dont want use username and password, I deployed application in WinServer 2003

Thanks
Vish

Sabarish
May 28, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

Hi,

1.I am using your example to create a Directory in our shared network (FileServer is part of our network)
2.I followed all your steps. It is changing enviromnent user name in the correct order i.e. ASP.NET, myusername and back to ASP.NET.
3. It works successfully when I run the code from Visual studio. Able to create the Directory.

But, I am getting "access denied" error when I am running from IIS.

Any ideas/clues

Thanks a lot for your quick response

Sabarish

Femi Ojemuyiwa
July 01, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

Very useful article. For all those having errors. Map the network paths to a drive on your machines first if file access is an issue or better still create a virtual directory to the folder within your application.

Syed Assad
July 31, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

Use this Class in your web app, its very clean and you can use it as follows, it also got rid of the acces denied message for me:

using (new Impersonator("uname", "domain", "password"))
{
try
{
....
}
catch (IOException ex)
{
// handle exception
}
}


public class Impersonator :
IDisposable
{
#region Public methods.
// ------------------------------------------------------------------

/// <summary>
/// Constructor. Starts the impersonation with the given credentials.
/// Please note that the account that instantiates the Impersonator class
/// needs to have the 'Act as part of operating system' privilege set.
/// </summary>
/// <param name="userName">The name of the user to act as.</param>
/// <param name="domainName">The domain name of the user to act as.</param>
/// <param name="password">The password of the user to act as.</param>
public Impersonator(
string userName,
string domainName,
string password)
{
ImpersonateValidUser(userName, domainName, password);
}

// ------------------------------------------------------------------
#endregion

#region IDisposable member.
// ------------------------------------------------------------------

public void Dispose()
{
UndoImpersonation();
}

// ------------------------------------------------------------------
#endregion

#region P/Invoke.
// ------------------------------------------------------------------

[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(
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);

private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;

// ------------------------------------------------------------------
#endregion

#region Private member.
// ------------------------------------------------------------------

/// <summary>
/// Does the actual impersonation.
/// </summary>
/// <param name="userName">The name of the user to act as.</param>
/// <param name="domainName">The domain name of the user to act as.</param>
/// <param name="password">The password of the user to act as.</param>
private void ImpersonateValidUser(
string userName,
string domain,
string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

try
{
if (RevertToSelf())
{
if (LogonUser(
userName,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}

/// <summary>
/// Reverts the impersonation.
/// </summary>
private void UndoImpersonation()
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}

private WindowsImpersonationContext impersonationContext = null;

// ------------------------------------------------------------------
#endregion
}

SVK
August 04, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

i am using file copy in asp.net
my asp.net application is on system1
my sqldatabase on system2

everything works fine when i run the application frm system1 ie the system having asp.net application

my file copy code is
File.copy(source,destination)

my source is system2 and destination is system1

uisng the application frm system1 using localhost/copypage.aspx
it works fine i am able to copy frm source to destination
web config has
<identity impersonate="true" userName="system2" password="abc"/>

but if run the same application thr' some other system (mapped & configured thr' IIS) i get error
now i get access denied
how do i go abt

Sri
August 14, 2009

# re: Using programmatic Impersonation from an ASP.NET Page

I want my ASP.NET application (VB.NET Code behind) to create a text file on a remote server(destServerName)

Dim destFilePath As String = "\\destServerName\desttemp\srcfilename.TXT"

Try
File.Create(destFilePath)
Catch ex As Exception
UtilityTier.ApplicationError.ReportError("SIInitAndEduInterface-btnUploadFile", ex.Message)
End Try

Exception Message:- "Logon failure: unknown user name or bad password"

Server destServerName is running Windows 2003

Folder 'desttemp' is having fullcontrol to Everyone,Network Service account

Tomas
February 17, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

I owe you a beer ;-), your code helped me a lot! thanks ...
but i still don't know why did not work my previous code ... i am trying to run from asp.net page bat files .. i used this code:

Process p = new Process();
p.StartInfo.UserName = AdHelper.domainAdmin;
p.StartInfo.Password = WMIHelper.securePassword(AdHelper.domainAdminPwd);
p.StartInfo.Domain = AdHelper.domain;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "xxx.bat";
p.StartInfo.Arguments = "qwerty";
p.EnableRaisingEvents = false;
bool retVal = p.Start();
log.Info("process start called, result: " + retVal);
p.Close();

when i ran web site from Visual Studio, it works great .. when i moved it to IIS, i get Access Denied exception on the row with p.Start() .. but i am sure, that file permissions to bat file are OK - it works in VS - i saw xxx.bat in taskmanager running under domainAdmin ...
Anybody has idea why this does not work?
It started working when i put before Process declaration that LogonUser and ImpersonateLoggedOnUser stuff ... but i still believe it should work even without it, using startInfo.domain/domainUser/domainPassword...
Thanks a lot, Tomas

satish
February 21, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

hi
I am using the exact code, as u have specified for impersonation, to connect to IBM WebSphere MQ, and it works fine in my local system XP, when I tried the same code on 64 bit Windows server 2003 it gives me bad image format exception, which I believe bcox of a 32 bit dll running on 64 bit OS. I am not sure, whether advapi32 dll or kernel32 dll is causing the problem?

and Will the code for impersonation works fine in 64bit computers?

misterandovas
February 26, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

Its fantastics, Thanks a lot,

Siderite
April 22, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

Hey, Rick! In my office people are using impersonation on web sites and WCF services. All of them EVENTUALLY get an access denied error that can only be solved by fixing/reinstalling the .Net framework. I am not working on the same projects, but I would like to find out what causes this and how to solve it.

I was wondering if you ever stumbled upon something similar. It seems to be directly or indirectly linked to IIS and impersonation.

SpinGee
September 30, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

Hi,
I have asp.net (impersonation = false) application with NTLM authorizaion so only authenticated domain users in group "A" can acces site. I have file system on network server which can acccess only users from group "A" with read/write access. Now i need temporarily impersonate user from group "A" to read files or directories on file server. Im doing it this way:
WindowsImpersonationContext ctx;
ctx = ((WindowsIdentity)User.Identity).Impersonate();
 if (System.IO.File.Exists(filePath))
                    {
                      //...
                    }
ctx.Undo();


It succesfully impersonate current user (Enviroment.User changes from NETWORK_SERVICE to current user). But file operations doesnt work becouse of some Logon failure. What im doing wrong? Strange thing is if i dont use this impersonation , it works.

Essay Topics
October 19, 2010

# re: Using programmatic Impersonation from an ASP.NET Page

I like this particular code because it formalizes the process, is easy to use, and will convert the API errors for you.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024