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

Understanding ASP.NET Impersonation Security


:P
On this page:

With ASP.NET applications it’s usually recommended that you run under the ‘ASP.NET user account’ without impersonation. The idea is that this account is a low rights account that can do little damage if for some reason the machine is compromised.

 

I get a lot of questions that are related to access rights for ASP.NET (and classic ASP) applications and 90% of the time the issue is related to the user underlying system account that IIS is running under. There tends to be some confusion in understanding just what account your application runs under and what rights need to be set to access this or that resource on the server. Usually the scenario involves a file on disk that needs to be accessed in read/write format.

 

First, to find out exactly which account your ASP.NET application runs under you can simply echo back Environment.UserName which is useful if you’re not that familiar with IIS or you’re running on an ISP box and they failed to provide you this information… You can stick:

 

<%= Environment.UserName %>

<%= Environment.UserName %>

 

into an ASPX page will tell you exactly which account the page is running under.

 

In all of my applications I tend to add one page in my admin directory that displays a bunch of information about the running environment. This page is fairly generic and it’s self contained so it’s easy to copy between projects (although I usually add a few admin functions). The following comes from my West Wind Web Store app:

 Application Status display form

 

Notice that there are two accounts that are listed: The underlying system account and the logged on user. These are two different things and the underlying system account is what Environment.UserName returns. The Logged on User in turn gets returned by User.Identity.Name which is a much higher level informational abstract that can be used by your application to figure out which user authenticated.

 

So, Environment.UserName returns to you the current Impersonation of the ASP.NET thread that you are running under. User.Identity.Name only returns you the authentication that ASP.NET has figured out based on the current request. So above I accessed a page with a Windows Login, hence it shows my username – rstrahl. If I displayed this on a standard non-logged in Web page it would show the IUSR_ account – the Internet Guest account.

 

What we’re interested in here is the underlying account which really determines what rights your ASP.NET application has to access system resources.  Now, the account that ASP.NET runs under depends on the Windows version, how you have configured your Web server and what settings are configured in your Web.Config file.

 

Web Server

If you are running IIS 5, the default account that IIS runs ASP.NET under is the ASPNET account. The actual account is configurable in machine.config. The ASPNET account is an account that ASP.NET installs and has fairly low rights. One big drawback in IIS 5 is that this account cannot be customized for each application – the ProcessModel key that sets this account lives in machine.config and cannot be overridden in web.config, so you basically end up with having the same account run all your ASP.NET applications.

 

On IIS 6 things are much more configurable. The default account used is NETWORK SERVICE but it’s actually configurable via a new feature called an Application Pool. With IIS 6 all processing no longer occurs in the INETINFO.EXE process, but rather is offloaded into one or more daemon process (w3wp.exe). You can configure one or more of these processes by adding Application Pools in the IIS management Console. You can then add virtual directories to specific Application Pools. Application Pools are quite configurable and one of the key options is the ability to specify an Identity that this process runs under.

 

 

By default this is Network Service, but you can change this to any account you see fit. Network Service is used because like the ASPNET account on IIS 5 it’s a low rights account which by default has access to next to nothing on your machine.

 

Web.Config

The next level of configuration for your ASP.NET application is web.config which allows you to specify the type of Impersonation is used with your ASP.NET application. By default ASP.NET – unlike classic ASP – doesn’t use any impersonation. Impersonation is the concept of the application pretending to be a different account than the underlying account running the application – ie. ASPNET or NETWORK SERVICE. In classic ASP IIS impersonated the logged on user which usually was the Internet Guest Account (IUSR_) or if you were logged in via Windows or Basic or Digest Authentication the user that was actually logged on.

 

ASP.NET works differently. It runs under the account that the process was started under originally. This means ASPNET or NETWORK SERVICE or if you’re using IIS 6 the account you have specifically configured for your Application Pool. So while ASP.NET provides different Authentication models to let you see who logged on to secure areas of your Web site via Forms or Windows Authentication, the underlying account in this scenario never changes. The Authentication is merely a tool for your application, but it doesn’t change the underlying security context.

 

This is a good thing and something that wasn’t really easily possible with classic ASP. You can however revert to the Impersonation model that works just like classic ASP by turning Impersonation on in web.config:

 

<system.web>

  <location path="admin">

    <system.web>

      <identity impersonate="true" />

      <!-- WS: Allow only Authenticated users -->

      <authorization>

        <!-- allow users="*"/ -->

        <deny users="?" />

      </authorization>

    </system.web>

  </location>

</system.web>

 

This option goes back to setting the underlying system account to the specific account that is logged on: The anonymous Internet Guest account or who ever is logged on. In this mode ASP.NET impersonates the current Web user. It gets this token from IIS which passes this account token on the ISAPI thread that originally fires off this request.

 

While this is not recommended generally, it can be a useful. I like to use this sort of setup for my Admin directories of an application. This makes it possible for my main application to run under a low privilege account, but allows my Admin paths to elevate the rights for users that have authentication to access a specifc directory of the application. Once the impersonation is in effect I can run under a specific admin account which will have rights for example to write to data in my application directory.

 

Directory Rights

So now we know which account is actually driving the application. The next step is to dole out permissions for your application in such a way that you can access the data you might need without compromising security. Which is not always easy and often means a compromise between security and flexibility.

 

The most common scenario I see is people needing to write some sort of output to the application directory. Usually people have problems when they need to write or access data in the Web Directory. Once you’ve figured out which account your application is actually running under you can start adjusting permissions as needed. So if you need to write to a file in your Web directory you need to give NETWORK SERVICE/ASPNET or whatever your app runs under rights to access this file. As always be very careful with this task and think ahead of how any security changes affect your security environment beyond just what you need to accomplish to access the file.

 

The easy way is to go in and give the required account the appropriate rights – give NETWORK SERVICE WRITE access for example in the directory. But again be careful here. General security guidelines would say – giving the operating account WRITE access might permit a hacker to upload ASPX pages and execute them. True, but you have to weigh that risk against the need to do what you need to do which might be to write an XML log file or write to web.config etc.

 

If you do need to open up security try to minimize your surface area. If you need access to a specific file give access only to that file. Even better – move any files you are accessing out of the script directories and into a separate folder. Remove anonymous access rights (assuming you don’t want Web site users to see the content) and then add read/write access for NETWORK SERVICE.

 

Here’s another little trick in this regard: One thing all my Web applications do is allow configuration settings to be stored in Web.Config using a custom Configuration class that allows reading and writing and serializing configuration data to various output formats. Web.Config lives in the application root of course along with most of the ASPX files. So I need WRITE access for my NETWORK SERVICE account right?

 

Well, no. <g> I can actually cheat by designing my in such a way that configuration settings are only updated from an Admin directory. I can set up impersonation on the Admin directory, disable access for anonymous users and voila I can now log in and gain elevated rights that do allow me write to the web.config file without changing the permissions (beyond making sure that my user account or group has WRITE access) on the default files. There's more detail about this scenario in this previous entry.

 

Note that you can restrict access to a directory either declaratively in web.config as a I showed in the previous section, or you can do it explicitly by setting directory permissions on a directory. If you have an Admin directory you can simply remove the Internet Guest account from the file permissions which will disallow all anonymous access to the directory without changing anything in you Web.config. In fact this may be desirable anyway if you store any sensitive data in the directory. The <location> tag only applies to files that ASP.NET processes (ASPX, ASMX etc.) but not static files like HTML, XML etc. So in some cases you may need directory rights anyway.

 

Programmatic Impersonation?

Note that it's also possible to affect the application's security environment programmatically from within your ASP.NET application by using some Windows API calls. There's more info on this topic in this previous entry about Using Programmatic Impersonation from an ASP.NET Page.

 

 


The Voices of Reason


 

Jeff Atwood
May 18, 2005

# re: Understanding ASP.NET Impersonation Security

Rick, I really like the diagnostic info you're showing here (ASP.NET counters, SQL counters, CPU counters). I have a similar about page which simply dumps all the assembly metadata and version information; I really struggled to think of any good diagnostic info to show other than assembly metadata:

http://www.codinghorror.com/blog/archives/000208.html

Can you share source for your diagnostic info?

Rick Strahl
May 18, 2005

# re: Understanding ASP.NET Impersonation Security

Jeff, they are just performance counters. Actually I shouldn't say that - it took me a while at the time to configure out how to get the percentage counters actually <g>. I remember looking for samples on how to read time intervaled counters and not finding any. I'll post another entry when I get a minute with the source.

Jeff Atwood
May 19, 2005

# re: Understanding ASP.NET Impersonation Security

> took me a while at the time to configure out how to get the percentage counters actually <g>

Well, right. So if you could share source it'd be much appreciated. My generic ASP.NET "about" page is pretty sparse at the moment; I'd love to add those counters.

MW de Jager
May 23, 2005

# re: Understanding ASP.NET Impersonation Security

I'm using IIS 5, so I do not have access pools. I tried your web.config recommendation for impersonation, but the app will not run now due to an error in web.config

Are you sure the sytax below is correct?

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


Kind regards
MW de Jager

Jason Dickey
June 14, 2005

# re: Understanding ASP.NET Impersonation Security

Great article! I've inherited an ASP.Net (IIS 5, Windows 2000) application that needs to copy a file to a network drive on a UNIX box. I'm using a UNC to give the path of the destination directory on the UNIX box. When I try to copy the file I receive the following error: System.IO.IOException: Logon failure: unknown user name or bad password... I've had a unix account setup for ASPNET on the unix side to allow ASPNET to copy to the Unix box. I'm wondering what else I need to do to get this to work (i.e. specifically in machine.config)? Do you have any suggestions?

Mark Smith
August 03, 2005

# re: Understanding ASP.NET Impersonation Security

Rick, great article. This cleared up a lot of things for me. I do have a bit of a problem at the moment though. I have an ASP.NET app that needs to read a log file on another server on our network. That server is a Windows 2000 box without the .NET framework. As such there is no NETWORK SERVICE account on the machine. What account do I use in this scenario?

victor
September 15, 2005

# re: Understanding ASP.NET Impersonation Security

I got the followinf error trying to read/write to Event Log :

Access is denied
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ComponentModel.Win32Exception: Access is denied

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[Win32Exception (0x80004005): Access is denied]



nick
September 19, 2005

# re: Understanding ASP.NET Impersonation Security

Ok, I have an ASP.NET application that can't access a Foxpro dbf file located on a seperate file server that is in the same domain as our IIS6 webserver. We're using the vfpoledb.1 Ole Db provider.

Locally it's all working fine. However when I deploy the website to our production (internal) webserver, IIS cannot access the DBF file. When the call to DbConnection.Open() is executed, an "Invalid path or filename" exception is thrown.

The connection string is a UNC path and I am using Integrated Windows Authentication (not anonymous/IUSR) with impersonate="true" in the web.config. When I run the code on my local development machine (to which I am logged into the domain as "ME"), it works fine. When I remote desktop (as "ME") into the webserver and attempt to browse to the UNC path, it can access the share no problem. Nevertheless, IIS can't see it.

I have tried what seems like every possible combination of impersonation, authentication, explicitly giving users rights to folders, etc but nothing seems to work. If I copy the DBF file to the website root on the webserver it obviously has no problems. Only when I try to access over the network does it blow up. Here is a code snippet:

DbProviderFactory f = DbProviderFactories.GetFactory("System.Data.OleDb");
DbConnection conn = f.CreateConnection();
conn.ConnectionString = "Provider=vfpoledb.1;Data Source=\\myuncpath;Collating Sequence=general";

DbCommand cmd = f.CreateCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;

cmd.CommandText = "SELECT count(*) FROM table1.dbf";

conn.Open(); //<-- Line that FAILS !!!

object Count = cmd.ExecuteScalar();
conn.Close();
cmd.Dispose();

I'm going crazy on this one so any help is appreciated thanks!

Harold
October 20, 2005

# re: Understanding ASP.NET Impersonation Security

Nick. You are describing the same type of problem I am experiencing. If you have found a solution, please post

Alison
October 24, 2005

# re: Understanding ASP.NET Impersonation Security

Rick, this article has saved my life. Thank you so much. We'd been struggling with permissions on trying to upload images via a UNC path and did everything any website ever had told us to do, but still no luck. Of course, we were trying everything under ASPNET account, and your comments about IIS6 using a different account put us on the right path and its now fixed after month's of struggling.

Your site is always informative and helpful and Im finding answers more and more often on your site. Thank you for your help.

weili
March 27, 2006

# re: Understanding ASP.NET Impersonation Security

I'm currently developping a web application
When I do this on my local machine (where I'm developping my application),
no problem occurs. But when I put the web application on my Windows server
2003 server, I always get the following error message. Can someone help me ?
Here is the config of my webconfig file :
<authorization><allow users="*" /></authorization>
<authentication mode="Windows" />
<identity impersonate="true"/>
And Here is the section process model of my machine.config file:
<processModel enable="true" timeout="Infinite" idleTimeout="Infinite" shutdownTimeout="0:00:05" requestLimit="Infinite" requestQueueLimit="5000" restartQueueLimit="10" memoryLimit="60" webGarden="false" cpuMask="0xffffffff" userName="machine" password="AutoGenerate" logLevel="Errors" clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect" comImpersonationLevel="Impersonate" responseDeadlockInterval="00:03:00" maxWorkerThreads="20" maxIoThreads="20"/>
Server Error in '/' Application.
--------------------------------------------------------------------------------

Access is denied
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ComponentModel.Win32Exception: Access is denied

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[Win32Exception (0x80004005): Access is denied]
System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo) +1104
System.Diagnostics.Process.Start() +85
System.Diagnostics.Process.Start(ProcessStartInfo startInfo) +49
Materiel.macposition.GetMac1(String IP)
Materiel.macposition.drptype_SelectedIndexChanged(Object sender, EventArgs e)
System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs e) +108
System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent() +26
System.Web.UI.Page.RaiseChangedEvents() +115
System.Web.UI.Page.ProcessRequestMain() +1099

--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:1.1.4322.2300; ASP.NET Version:1.1.4322.2300

maybe there are some questions on web.config or machine config

Thanks in advance for all responses !

Alejandro
May 29, 2006

# re: Understanding ASP.NET Impersonation Security

Hi, I've a webapp that need to copy a file to another server via UNC.

When I've tried to copy it I get and access denied.. If I copy the file with the explorer it's works fine. I suppossed that it's trying to copy the file with Network Services Account.

The WebApp is running on IIS6 and target directory is under W2K3. The WebApp is config only for Windows Integrated Security and the web.config has <authentication mode="Forms" />
<identity impersonate="true"/>.

Could you help me??

Regards

Rick Strahl
May 29, 2006

# re: Understanding ASP.NET Impersonation Security

Security in your case is the server account that is runn your Web Application. Use <%= Environment.UserName %> to figure out what user account that is exactly. That account must have rights to write your file on the remote machine - not likely it will. You're only other option is to use Impersonation on specific pages and force a different login that does have rights on the remote.

Keith Rutherford
May 31, 2006

# re: Understanding ASP.NET Impersonation Security

Good Article. What about impersonating a local admin account on a remote machine for stuff like regestry reads from asp.net?

I am doing impersonation in my code behind (vb) to access the event log on a remote machine. I can put a domain admin in the web.config but I dont want to do that. Each machine has a machine admin that I would like to impersonate. Any ideas?

Keith

Amit
July 30, 2006

# re: Understanding ASP.NET Impersonation Security

Hi, I read ur article. It is really very Informative. Thank you. Can u pls. help me in a problem we are facing. Its the same as described by nick with only one exception that the remote machine is a novell 5 file server. If i caopy hte dbf file to any local drive on my develpment machine it rocks rest it reports in invalid path or file name error. I tried ur suggestions in this article but could no get ne thing fruitfull out here. I m using IIS6, ASP.net 1.1
Thank you....

Deepak Ranjan Sahoo
August 12, 2006

# re: Understanding ASP.NET Impersonation Security

Hi,
This is Deepak. In my opinion Impersonation is a technique, by which instead of using a same account for all the users asp.net provides a userid by which all the usres can access the page by using that account.

Rick Strahl
August 12, 2006

# re: Understanding ASP.NET Impersonation Security

Keith, you either have to use a domain account or a local user account that exists on both machines with the same username and password.


hemant tawri
August 29, 2006

# re: Understanding ASP.NET Impersonation Security

i want validation expression for the url but(.)dot is not multiple like http://www.........yahooo..........com
so what i do

Rick Strahl's Web Log
September 27, 2006

# Displaying useful Configuration and Status information in an ASP.NET app - Rick Strahl's Web Log

When I build an ASP.NET or any kind of Web Application for that matter, one of the first things I do usually is add an informational page that captures some useful information about the application and echos it back. Several people asked about where this info comes from so I'm posting it here. Obviously there's much more information available and you can choose to include as little or as much of that as you see fit.

Rick Strahl's Web Log
September 28, 2006

# Installing a Printer Driver programmatically - sort of - using PrintUi.dll - Rick Strahl's Web Log

Installing a printer under program (or batch) control is easy to do with PrintUi.dll which allows many configuration tasks through a command line utility.

Rick Strahl's Web Log
September 28, 2006

# Configuration File Settings and ASP.Net Security - Rick Strahl's Web Log

Somebody brought up a good point about my Configuration Settings class today that I failed to mention in the article: Security requirements for an ASP.Net application to be able to actually make changes to the .Config file.

Rick Strahl
October 04, 2006

# Using programmatic Impersonation from an ASP.NET Page - Rick Strahl

Ever have an ASP.NET page that doesn't have the rights you need and wish you raise permissions to do what you need? Well, you can do it using various System APIs but use with care.

# Google Groups: microsoft.public.dotnet.framework.aspnet


Rick Strahl's Web Log
November 16, 2006

# Using programmatic Impersonation from an ASP.NET Page - Rick Strahl's Web Log

Ever have an ASP.NET page that doesn't have the rights you need and wish you raise permissions to do what you need? Well, you can do it using various System APIs but use with care.

Kesney Fontes
January 02, 2007

# re: Understanding ASP.NET Impersonation Security

Nice explanation. Thank you, it was helpful.
Kesney Fontes
(One at nossobrasil.net)


January 28, 2007

# Bily - 博客园


Gary
January 29, 2007

# re: Understanding ASP.NET Impersonation Security

I am having a really hard time trying to access remote resources through an ASP.NET web app without giving NETWORK SERVICE access to them.

Impersonation does not work when I try to access resources on a remote machine. I only have "Windows Authentication" enabled for my web application and IE is also set up for this. By passing the user token from User.Identity to WindowsIdentity.Impersonate() method, the Environment.UserName property reflects my domain account. So far, so good. Within this impersonation context, I try to access the UNC path which my account does have access to. I get an "Access Denied" error every time.

I have also tried creating a separate account in a new application pool, adding it to IIS_WPG, running the iis script for enabling WPG on an account, and I have even explicitly gave it all permissions NETWORK SERVICE is usually granted through Local Security Policy. I got the list of permissions from Microsoft's site. This allows me to give access only to this one web application to the UNC path. However, I only want to let certain domain users in, and when I change the Application Pool's identity to this special user, Windows Authentication no longer works. I get a 401 error. I have tried all available authentication methods in the IIS configuration, but nothing is working.

When I access the UNC path from my machine with my domain account I can access it, but it just won't work through impersonation, and I can't authenticate my domain user if I use anything other than NETWORK SERVICE for my app pool. Also, my domain account and the special WPG user I created both have full access to inetpub on this server right now, and I'm still getting nowhere.

Does anyone have any ideas?

Rick Strahl
January 29, 2007

# re: Understanding ASP.NET Impersonation Security

The best thing in this scenario is to not use NETWORK SERVICE as your account, but create an account and use that instead. It's much easier to apply permissions to a standard account and you won't have to worry about mucking with SIDs etc. With a special account you can set the default permissions and then when needed continue to use Impersonation to elevate permissions if necessary.

Gary
January 29, 2007

# re: Understanding ASP.NET Impersonation Security

Thanks for the response, but this does not work the way I need it to. As I mentioned before, I have tried using a special domain account instead of NETWORK SERVICE and gave it the proper permissions. This gives the web app access to the UNC path and its files, but Windows Authentication between IE and IIS doesn't work, so I can't find out if the person accessing the web page should have access. I don't want everyone to be able to see this page. I get a 401 unless I enable anonymous access. The domain user of the client does have full access to the web's directory and to the UNC share, so it seems like Windows Authentication is just not working or is perhaps not allowed in this scenario. I must be missing something.

Any ideas?

Rick Strahl
January 29, 2007

# re: Understanding ASP.NET Impersonation Security

Use a local account on both machines with the same username and password. BUt a domain account should work as long the Web Server can authenticate that user (ie. it's part of that domain). Generally IIS looks for local accounts for authentication though...

Gary
January 31, 2007

# re: Understanding ASP.NET Impersonation Security

I tried both a domain account and adding an identical local account to the file server. In both of these scenarios, I am still unable to get Integrated Windows Authentication to work between IE and IIS, regardless of whether the worker process has access to the file system. Therefore, with this method, I am unable to determine who the client is.

I did finally get my application to work the way I want it to. I had to go back to using the NETWORK SERVICE account so I could use Integrated Windows Authentication, I enabled impersonation for the web application, and I enabled delegation on the web server. It was as simple as enabling a checkbox in Active Directory, and I don't need to create special file system permissions.

Thanks. :)

VS
February 13, 2007

# re: Understanding ASP.NET Impersonation Security

Hi there

I have been working on this for quite some time but could not figure it out.

The application that I am working on is a classic ASP.

We have to use an impersonated account with the username and password which should be picked up from Registry (as in ASP.NET).

The reason we have to do this is related to the account settings that we have in the .NET Web Service that we are calling from this Classic ASP application.

What would you advise in this situation.

Thanks
VS

闫炜的专栏
May 28, 2007

# 闫炜的专栏 - Enterprise Library


Brendan Tompkins
May 31, 2007

# Run a .BAT file from ASP.NET - Brendan Tompkins

TDD .NET Agile ADO.NET VB C# ASP.NET

Brendan Tompkins [MVP]
July 04, 2007

# Run a .BAT file from ASP.NET - Brendan Tompkins [MVP]

TDD .NET Agile ADO.NET VB C# ASP.NET

Steve Lang
January 03, 2008

# re: Understanding ASP.NET Impersonation Security

Great article Rick.

Is there a benefit to using Environment.UserName instead of WindowsIdentity.GetCurrent().Name?

Environment.UserName requires EnvironmentPermission with read access to UserName setting.

WindowsIdentity.GetCurrent() requires SecurityPermission with ControlPrincipal flag.

Both require medium trust or higher.

Environment.UserName is not prefixed with DomainName, so technically it is not a complete account name. In your example, System Account running app would display ASPNET instead of RASNOTEBOOK\ASPNET.

Steve Lang

danny schoofs
March 08, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

I'm pretty well informed about how IIS works with security and impersonation. But with IIS7 I discovered something so strange while installing a classic ASP webapplication that I just can't explain it. Unfortunately it requires a lot a explanation to understand the problem so maybe it's better if I just give a link to another forum where I already posted it: http://www.thescripts.com/forum/showthread.php?p=3098722#post3098722
If anybody has any idea how this is possible, it would be much appreciated.

Danny Schoofs

Rick Strahl
March 08, 2008

# re: Understanding ASP.NET Impersonation Security

@Danny - the problem with ASP classic is that it ALWAYS uses impersonation when running with Windows Authentication. it'll always impersonate the account that is accessing the page and hence the security will change as different authenticated users access the site. Contrast this to ASP.NET which gives you options whether the machine account is used (default behavior) or whether authentication is applied. The latter is rarely a good idea, but that's all ASP classic can do. So generally you end up with IUSR_ or whoever is logged in and you need to give all those users read/write access to your data.

danny schoofs
March 09, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

Thx for the help but how can a process running under the same account, impersonating the same account always work except in one case where I get 'write access denied' to a folder that every user and group on my machine has complete access to ?

Facts:
1) using only anonymous authenticaton configured to run under 'my account' for this test (and not the default IUSR)==> process: 'NETWORK SERVICE', impersonating 'my account' ==> write access OK
2) using only windows authenticaton ==> process: 'NETWORK SERVICE', impersonating 'my account' ==> write access ONLY ok when I started IE with the 'run as admin' option.
3) I gave every group and/or user on the machine full access to that folder/file, and 'my account' is member of the admin group.

Remember I'm using IIS7 on vista business. I just makes no sense. Could it be a bug ?

Rick Strahl
March 09, 2008

# re: Understanding ASP.NET Impersonation Security

Simple - you're not running under every account. The easiest way to check this is write out the actual username you're running under or echo it back or whatever. If you're using a VFP COM component have a method that echos back sys(0) and it will tell you what account.

Like I said before App Pool configuration has no effect on ASP classic since it always impersonates the logged on user which is either IUSR_ or whoever is logged in.

IAC, if you have problems with COM object security the easiest way to fix this is to run the component in COM+ and configure the server to run under appropriate Impersonation. That way the guesswork goes out of COM activation and passing forward the security context to COM.

danny schoofs
March 11, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

Thx again. I must be missing something simple here, because I don't really see how your explanation relates to this specific problem. I know the account that's being impersonated (it's the acount I called 'My Account' that I used to log on to the computer as I'm using only windows authentication for the IIS virtual directory), I also see this with Sysinterals 'process monitor'. I just don't understand the 'write access denied' to a folder that account can absolutely write to, and that I do not get it when I started Internet Explorer with the 'run as admin' option (the account is member of admin group). I'll just let it sink in, maybe it will come to me. Currently, when looking at the facts, I still think it's a bug. How can it possible be that when allowing only anonymous authentication for the same IIS virtual directory, and configuring it to run under that same account (not IUSR) everything works, even when I did not start IE with the 'run as admin' option. The same account is being impersonated then.

Imre
March 30, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

I'm seeing the same issue as Danny (Classic ASP & IIS 7), where if I use basic authentication everything works just fine.
I tried using windows authentication and gives "Access denied" when server script is writing to a file, or trying to access a network share.

Process Monitor shows the impersonation of the same user when writing to the file for both basic and windows authentication.

The only difference I saw was when looking at Process Explorer, the security context tokens looked different
- For basic authentication w3wp.exe (Working)
Token NT AUTHORITY\IUSR:3e3
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token domain\Imre.Lengyel:1db04b7
Token NT AUTHORITY\IUSR:3e3

- For Windows Authentication w3wp.exe (not working)
Token NT AUTHORITY\IUSR:3e3
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token NT AUTHORITY\NETWORK SERVICE:3e4
Token domain\Imre.Lengyel:2dfc4
Token domain\Imre.Lengyel:2dfc4
Token NT AUTHORITY\IUSR:3e3

an ideas what does the numbers mean in the token names, and why are they different for my login name when using basic and windows authentication?

Nitin
March 31, 2008

# re: Understanding ASP.NET Impersonation Security

Hi
I'm trying to access a file over a network by providing a UNC path ("\\system\drive\directory\File.jpg") but I'm getting a <code lang="c#">System.IO.FileNotFoundException</code lang="c#"> exception. I've tried using Impersonation and providing the userid and password of the system running the web service but still getting the same error. Also I'm able to access the image from other systems but not from one system. I've tried giving all the permissions on the parent directory of the image but nothing helped the matter.

Any ideas???

Thanks

Arvind
August 05, 2008

# re: Understanding ASP.NET Impersonation Security

i have created one web application which is running fine on production. but one warning is frequently logged in event viewer. I have used ASP.NET 2.0 ,VB.Net and SQL server 2000 and hosted on windows 2003 server. Below is the error detail.. Does anyone have any ideas?

Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 7/19/2008 9:36:20 AM
Event time (UTC): 7/19/2008 7:36:20 AM
Event ID: 894dc77a37eb434ab99cead39883fd61
Event sequence: 2012
Event occurrence: 8
Event detail code: 0

Application information:
Application domain: /LM/W3SVC/218917769/Root-21-128608804971939957
Trust level: Full
Application Virtual Path: /
Application Path: E:\inetpub\legalintelligence\
Machine name: LGI-WWW1

Process information:
Process ID: 11948
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE

Exception information:
Exception type: Win32Exception
Exception message: The logon attempt failed

Request information:
Request URL:
Request path:
User host address:
User:
Is authenticated: False
Authentication Type:
Thread account name: NT AUTHORITY\NETWORK SERVICE

Thread information:
Thread ID: 17
Thread account name: NT AUTHORITY\NETWORK SERVICE
Is impersonating: False
Stack trace:


Custom event details:

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp [^].

Arvind
August 05, 2008

# re: Understanding ASP.NET Impersonation Security

i have created one web application which is running fine on production. but one warning is frequently logged in event viewer. I have used ASP.NET 2.0 ,VB.Net and SQL server 2000 and hosted on windows 2003 server. Below is the error detail.. Does anyone have any ideas?

Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 7/19/2008 9:36:20 AM
Event time (UTC): 7/19/2008 7:36:20 AM
Event ID: 894dc77a37eb434ab99cead39883fd61
Event sequence: 2012
Event occurrence: 8
Event detail code: 0

Application information:
Application domain: /LM/W3SVC/218917769/Root-21-128608804971939957
Trust level: Full
Application Virtual Path: /
Application Path: E:\inetpub\ApplicationName\
Machine name: LGI-WWW1

Process information:
Process ID: 11948
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE

Exception information:
Exception type: Win32Exception
Exception message: The logon attempt failed

Request information:
Request URL:
Request path:
User host address:
User:
Is authenticated: False
Authentication Type:
Thread account name: NT AUTHORITY\NETWORK SERVICE

Thread information:
Thread ID: 17
Thread account name: NT AUTHORITY\NETWORK SERVICE
Is impersonating: False
Stack trace:


Custom event details:

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp [^].

# yahoo style categorization directory

This is your business and you have worked really hard to put this up. So do not just sit back and relax once you hand over the search engine optimization work to a firm that has trained professional. You must keep a constant track of the work which is being done and see if this is bringing results for your business or not. You are best judge to know if your business is benefiting from the search engine marketing strategy or not. If the strategy is not working out for you, sit and talk to the professional and...

Sreedhar
August 21, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick,
Thanks for the wonderful explanation on impersonation within IIS and ASP.NET. I have a web application developed in ASP.NET 1.1. A particular section of the website needs to write a file to a UNC share on a remote server. The UNC share is configured in the web.config file. The application is running on IIS 6.0 (Windows 2003 SP2) in the Default App pool with the default identity "Network Service" account. The application is configured for "Integrated authentication". The Web.config file has the <impersonate=true> key. Without "constrained delegation", the file write operation (implemented in the ASPX page) to the remote share fails. However, after enabling "constrained delegation", the application is able to write to the file share. However, when I try to see the "owner" of the file, it is defaulting to the local administrators group of the "File share server", as opposed to the original authenticated user of the web application. Is this by design Or am I missing something here? I did verify that the file was created and written by using the original logged on user - I did this by turning on "object access" auditing and then viewing the audit events for the directory in the event log. The event log displayed the authenticated userID's kerberos call to the file-share server from the web server.
Even if I change the App pool identity to a domain user account, the file is still being written/owned by the local file share administrators group.
Any insight into this behavior would be quite appreciated.
Thanks.
-Sree

Ron
August 27, 2008

# re: Understanding ASP.NET Impersonation Security

Just wanted to say this was a great article. They way you explain everything is so clear and I love it. Thanks for the great information. God bless.

gg
November 11, 2008

# re: Understanding ASP.NET Impersonation Security

Hi Rick

We are in process of moving website to a new server.

Current Server - Win 2000 ,IIS 5.0
New Server - Win 2003, IIS 6.0

The website works prefectly fine on the current server but gives the "Access denied" error on the new server. Any idea? When I tested for the <%= Environment.UserName %>, result was : webuser

Here is the error log:


Access is denied
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ComponentModel.Win32Exception: Access is denied

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[Win32Exception (0x80004005): Access is denied]

[InvalidOperationException: Cannot open log for source {0}. You may not have write access.]
System.Diagnostics.EventLog.OpenForWrite() +363
System.Diagnostics.EventLog.WriteEvent(Int32 eventID, Int16 category, EventLogEntryType type, String[] strings, Byte[] rawData) +280
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) +462
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category) +21
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID) +15
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type) +11
Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.PerformanceCounterInstances.ReportCounterFailure(String message)
Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.PerformanceCounterInstances..ctor(String categoryName, String counterName, Boolean createNewInstance)
Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.InstrumentedEvent.AddPerformanceCounter(String category, String[] counterNames, Boolean createNewInstance)
Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.InstrumentedEvent.Initialize(String counterCategory, String[] counterNames, Boolean createNewInstance, String eventLogSource, EventLogIdentifier[] eventIds)
Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.InstrumentedEvent..ctor(String counterCategory, String[] counterNames, Boolean createNewInstance)
Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataServiceEvent..ctor(String[] counterNames)
Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataCommandFailedEvent..ctor(String[] counterNames)
Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataCommandFailedEvent..cctor()

[TypeInitializationException: The type initializer for "Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataCommandFailedEvent" threw an exception.]
Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataCommandFailedEvent.Fire(String commandText, String connectionString) +0
Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataInstrumentationFacade.CommandFailed(String commandText, String connectionString)
Microsoft.Practices.EnterpriseLibrary.Data.Database.DoLoadDataSet(DBCommandWrapper command, DataSet dataSet, String[] tableNames)
Microsoft.Practices.EnterpriseLibrary.Data.Database.LoadDataSet(DBCommandWrapper command, DataSet dataSet, String[] tableNames)
Microsoft.Practices.EnterpriseLibrary.Data.Database.LoadDataSet(DBCommandWrapper command, DataSet dataSet, String tableName)
ABC.Reports.PSRReport.PSRCalculator.LoadPSRs() +186
ABC.Reports.PSRReport.PSRCalculator.Process() +12
Intranet.Reports.Pages.pagePSRProductivity.BindData() +149
Intranet.Reports.Pages.pagePSRProductivity.Page_Load(Object sender, EventArgs e) +29
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +750




--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:1.1.4322.2407; ASP.NET Version:1.1.4322.2407

mak
February 16, 2009

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

Thanks for great article, it cleared lot of my long pending doubts.

I have one query realated to impersonation about my current project, I am having SQL Stored Procedures which has business logic implemented based on which user is accessing these Stored Procedure and depending upon users its out put gets changes, basically it does authorization based on user identity in Database level.
Now I wanted to run the ASP.NET under Network Services and without Impersonation setting On, in such cases what Identity would ASP.NET pass to Database? will it be Network Services or logged in user that is (page.user.idenity)?
And what should I do to always pass it as user identity and still keep impersonation off?

Thanks in advance

Mak

Maxime D
March 13, 2009

# re: Understanding ASP.NET Impersonation Security

Thank you for this article, was very helpfull to me ! Understood my mistake I've been tracking for a couple of days...

Alex
March 30, 2009

# re: Understanding ASP.NET Impersonation Security

Hi, Rick.
Very useful article. I have practical question about impersonation. I have simplest web service, which returns me WindowsIdentity.GetCurrent().Name and (WindowsPrincipal)Thread.CurrentPrincipal.Identity.Name.
I have
<authentication mode="Windows" />
<identity impersonate="true"/>
in the web.config file of this service. Anonymous authentication is disabled and Windows Integrated Authentication is turned on on the server machine.

Client of this server has:
service.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

We have LDAP Active Directory.

In first scenario, this webservice is running on the Win2003 server with IIS 6.0. If I call this web service from some client machine it returns me correct name of the user currently logged on on the client machine. I tried to run client application on the different computers and every time it seems to work correctly.

In second scenario I installed the same web service on WinXP machine with IIS 5.0 and I try to call it from client machine. Service returns me name of the user, currently logged on on the WinXP machine, not on the client – looks like service cannot impersonate my remote client correctly in this scenario.

So my question here – is it the problem of configuration, or it is something principal, which cannot be implemented with IIS 5.0.

Nicolas
May 05, 2009

# re: Understanding ASP.NET Impersonation Security

Great article Rick,
Thanks for that. These permissions issues are so painfull when you don't know what is going on.

Feel free to send a mail if you want some tips on the western australian windsurfing spots ;-)

Enjoyed the pic of the backloop with the gopro hero. Any good videos to share?

Thanks
Nic

Joe
June 03, 2009

# re: Understanding ASP.NET Impersonation Security

Hello,

that was a good article but has not helped me resolve a problem I've been struggling with unfortunately losing, so am turning to you for help in frustration. My application is impersonating a domain user to access a network resource using the WindowsIdentity Impersonate method from an ASP.NET page, running in an application pool with default settings on IIS6. This code switches context as expected as you can see the Thread Account Name picks up the appropriate domain name, whereas the process Account Name still runs as NETWORK SERVICE. This domain user account has rights to open the file but is throwing a WinIOError saying "Insufficient system resources exist to complete the requested service" when I try and use Response.WriteFile or Response.TransmitFile to send the document to the client's browser. The document itself though is only 24KB so is fairly trivial and it streams fine if I use the NETWORK SERVICE account instead using the exact same code. I've explored the Adjust Memory Quotas For a Process and Replace a Process Level Token for the Local security policy on the server adding domain users to these rights but without success. I can't see any access issues using Regmon although Filemon picks up the resources error as expected but nothing else. All of which has left me stumped - is there another setting I need to be adjusting on the server/pdc - any suggestions very gratefully received?!

Mike
June 13, 2009

# re: Understanding ASP.NET Impersonation Security

Very informative write-up, Rick. Will the call to Environment.Username work in a classic asp
page as well as in an ASP.NET page? If the answer is no, do you know what call I can
make in a classic asp page to obtain the identity of the underlying process?

Mike
June 14, 2009

# re: Understanding ASP.NET Impersonation Security


By the way, the reason for my question about what call to make to obtain the underlying system account from classic asp, is that I plan to user wildcard mapping to graft ASP.NET 2.0 forms authentication onto a classic asp web app. In a hybrid situation like that, it isn't clear to me whether impersonation will be turned on or not. I assume that System.Environment.UserName is only available in ASP.NET, not in classic asp.

Manuel Moniz Pereira
June 24, 2009

# re: Understanding ASP.NET Impersonation Security

Hello,

Great article.

I have a problem, in my ASP.NET application. It's an old app and it still uses .NET 1.1.

I have a WebService, which has to write some files to a network directory. The network directory will have to be specified in the form of UNC path.

I use impersonation to a user which has admin privileges on the remote server (for testing purposes).

While debugging, I have a breakpoint right before the call to impersonation, and Environment.Username returns ASPNET. After the call, Environment.Username returns the correct user with the admin privileges, so everything went well.

Nonetheless, on the webservice, I call System.IO.Directory.Exists("\\myServer\MyDir"), and I'm certain the path is correct, and it always returns false. If I call System.IO.Directory.Exists("C:") it returns true.

Could you give a hint as to what to do?

Thank you in advance,
Manuel Moniz Pereira

Rick Strahl
June 24, 2009

# re: Understanding ASP.NET Impersonation Security

A Web Application by default doesn't have rights to network paths. NETWORK SERVICE can't even see remote paths. Beyond that .NET in general has no rights in network paths unless you set up .NET Security and allow the remote machine as part of the Zone configuration.

Without either of these remote machines are not even visible.

Greg
October 15, 2009

# re: Understanding ASP.NET Impersonation Security

Hi Rick,

I have a similar situation to Manuel Moniz Pereira above (24 June 2009).

My web application running on server A needs to get a list of the files in a directory on server B and then allow them to be downloaded. I am impersonating a network user and I can see, by using Environment.UserName, that my user is changing from NETWORK SERVICE to my network user. This user has access rights to the directory but I am still getting the error "Access to the path .... is denied".

I was hoping you could elaborate on your response as to what needs to be done to allow access.

Thank you!!

Doug
November 11, 2009

# re: Understanding ASP.NET Impersonation Security

I've visited this page several times. It is a frustrating problem! My app runs fine on dev (VS2008), but gives "Access to the path is denied" when run from production. The problem line is:
File.Move(tmpFile, ctlFile);
where ctlFile is a string referring to a valid UNC share (valid because the same string works on my box). I have impersonation enabled, and
Page.User.Identity.Name;
System.Security.Principal.WindowsIdentity.GetCurrent().Name
System.Threading.Thread.CurrentPrincipal.Identity.Name
Environment.UserName
all return the same user (me!). I've even moved the application to its own application pool and set the identity to a network-level admin, thinking that the worker process identity might be involved, too. But no joy.

Is there a tool that will report which machine or subsystem is blocking the action and why? I'm imagining the File.Move command progresses through a series of security gates, and one of them (at least) isn't opening. But which? There ought to be a more methodical way to handle permission problems than to keep throwing privileges at the app until it finally starts working.

kumar
January 17, 2010

# re: Understanding ASP.NET Impersonation Security

Hi
i have a peculiar problem rendering background images into an exported pdf document.
i have a web page which is exported to PDF using a thirdparty dll.
this web page has images, background images, and some text, CSS.
when my app pool identity is "NETWORKSERVICE" i get the pdf with all images,text and proper CSS. when when i run my application under "IWAM_<SYSTEMNAME> account the background is missing in the generated pdf.
i've been struggling with this problem since few days and not able to figure out what is going wrong.
Need your expert advice on how to figure this out.

what is driving/forcing the background image into pdf when the app pool account is NETWORKSERVICE?

any help is highly appreciated.

thanks
kumar

Apurva
January 26, 2010

# re: Understanding ASP.NET Impersonation Security

Hi,

I am facing an issue with Classic ASP. I have a website which uses ASP pages and .Net 1.0 pages. I am trying to call SAP through RFC calls from ASP pages. I created a .NET component which i have registered as COM. Every things works great till now, but when i am trying to call SAP, it is trying to write in C:/WINNT/TEMP folder and it is giving permission denied error.
As per the above explanations, ASP pages uses IWAM account, which dont have write permission on Temp folder and also i can't give this permission due to security issues.

Could you please suggest me, is there any way to run ASP pages under ASPNET acccount?

Thanks,
Apurva

danish
September 02, 2010

# re: Understanding ASP.NET Impersonation Security

Hi,
I created a user on the webserver and gave "act as operating system" privilege. I can impersonate and access whatever I want within the same workgroup or domain.

But, I want to access the fileserver which is on different domain. I have tried but I am unable to do it. Please let me know if it is possible. If yes then how?

Please help.

/Danish

John T
November 11, 2010

# re: Understanding ASP.NET Impersonation Security

Thank you. Thank you. Thank you.

This article really cleared up a great deal of confusion I had. Can't thank you enough for sharing this knowledge.

regards
John T.

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