Useful tools
Before you attempt to fix anything that is broken, you need to
familiarize yourself with a few tools which will help you narrow down the
issue. In our case, we would be interested in tools like FileMon, RegMon, and
Security Auditing. For more information about FileMon, visit the following Microsoft Web site:
For more information about RegMon, visit the following Microsoft Web site:
Drill down to isolate the problem
- Has the application ever worked? If yes, then what changed
that could have made the application break? It's possible that software updates or
security updates were applied on the server. A code rollout also could have
caused the issue.
- Do simple .html and .asp pages serve from IIS?
- Was the application migrated to a different version of
IIS?
- Do other ASP.NET applications on the server fail with the
same error? Is this the only application that fails?
- Does the issue occur for all users or for only specific users?
- Is the issue reproducible while browsing locally on the
Web server, or is it reproducible for only a few clients?
- If you are using impersonation, then does the impersonated
user have the necessary access to the resource?
The above questions are useful in order to diagnose a problem.
If you are posting your issue on any of the ASP.NET forums, and if you
already have the answers to most of these questions, then it's likely that you
will get a quick pointer or solution to your problem. The key is to post the
whole ASP.NET stack trace error, if applicable, instead of saying "I am getting
an Access Denied error while trying to run my ASP.NET application. Can anyone
help?" It's much easier for someone to look at the stack trace and give you
pointers when they can see a complete error message. So you need to ask
yourself...
What is the exact error message?
The first question we ask customers is, "What is the exact error
message?" If you have a clear description of the error message thrown by the Microsoft .NET Framework,
you can skip this section. If your application masks the actual error message
and gives you a friendly error message instead, such as, "An unexpected error has
occurred. Please contact the website administrator for details," it's not of
much use to anyone. Here are a few steps which will help you get the actual
error message.
- Locate and open the Web.config file in the application
directory and change customErrors to mode="Off". Save the file, and reproduce the
problem.
- It still might not be possible to see the actual error
message after following the above step because of custom event/error handling
done by the application developer. You can try to locate the Application_Error
event in the Global.asax file and comment out any code that uses the
Server.Transfer("Errors.aspx") function to go to a custom error page.
/Global.asax
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
//Server.Transfer("Errors.aspx");
}
Once you get the actual error message, read it to determine if the
error is caused by missing permissions on a local resource or on a remote resource
that your ASP.NET application is trying to access.
Tip You can contact your developer to find out how to see the actual
error message. It's possible that your developer may be logging it to a file or getting
e-mail notifications. Always remember to make a backup of any file that you are
going to change. With a backup available, you can always roll back any changes.
Issue occurs because of missing permissions on a local resource that the ASP.NET application tries to access
If you are unable to get a clear description of the problem
because of a custom error message, run FileMon and reproduce the problem. Stop
and save the capture as FileMon.xls and open the file in Microsoft Excel. On the
Data menu, click
Filter, and then click
AutoFilter to use the filtering capabilities of
Excel. Now select the drop-down list in column F and look for "ACCESS DENIED"
errors.
A sample FileMon output is shown below.
10381 1:01:11 PM w3wp.exe:2320 OPEN
C:\winnt\microsoft.net\framework\v1.1.4322\Temporary ASP.NET
Files\sessiontest\8832e585\275ec327\global.asax.xml ACCESS DENIED NT
AUTHORITY\NETWORK SERVICE
As you can see from the filtered
results, we have narrowed down the cause of the problem. FileMon shows that the NT
AUTHORITY\NETWORK SERVICE account is missing NTFS permissions on the
C:\Winnt\Microsoft.net\Framework\v1.1.4322\Temporary ASP.NET Files folder.
This should be straight forward to fix.
For more information about using FileMon to troubleshoot ASP.NET, click the following article number to view the article in the Microsoft Knowledge Base:
890960Â
(http://kbalertz.com/Feedback.aspx?kbNumber=890960/
)
Troubleshooting ASP.NET using FileMon
Tip A good step would be to change the ASP.NET process account to an
Admin account to see if it fixes the problem. In IIS 5.x you would change the
userName to "SYSTEM" in the process model section of the machine.config file
and in IIS 6.0 you would change the IIS AppPool identity to "Local System" to
see if the application works.
Note This should not be used as a solution, but
only as a troubleshooting step.
Most people would tend to
reinstall the Microsoft .NET Framework or even go to the extent of reinstalling the
operating system. This is not a recommended troubleshooting step and does not
guarantee that the issue will not reoccur. I will provide one such example.
Intermittent issues are often hard to isolate and troubleshoot. In this
scenario the customer's application would work fine for a few hours, and then all of
a sudden it would fail with the error below. The customer had already tried reinstalling
the .NET Framework as well as the operating system. This seemed to fix the
problem for a few days, but then it reappeared.
Collapse this imageExpand this image
Running FileMon did not show any ACCESS DENIED
errors. All the necessary permissions for the ASPNET account were in place. The
only way to recover from the problem is to reboot the box. Even an IIS reset
would not help. You are thinking "Ah, Microsoft Software always needs a reboot
to recover?" Well, you are wrong!
The key here is to look closely at
the error message. The error clearly says "cannot open a file for writing," and
not the usual ACCESS DENIED error, so I am thinking that it's some other process
that is holding a lock on a file or folder and not allowing ASP.NET to write
to it. It makes sense that a reboot was killing the other process and the
ASP.NET application starts working again until the rogue process locks the file
again. The logical thing to do would be to turn off all antivirus programs, third-party spyware, or any other file monitoring software that runs on
the server. I do not
want to point out any specific third-party software. But, in general, antivirus software
is known to cause a lot of grief for IIS and ASP.NET applications. Another
known issue caused by antivirus software is session loss due to AppDomain
recycles when the Bin folder or the .config files are touched.
Tip The easiest way to turn off third-party services is to:
- Click Start, click Run, and then type msconfig.
- Select Services and check Hide All Microsoft Services.
- Click Disable All to stop the third-party services.
- Click Start, click Run, and then type iisreset to reload the CLR into the worker process.
Monitor your application to see if the issue reoccurs. If
you run multiple antivirus programs, use the trial-and-error method to
determine which particular program is causing the issue.
Note If the same error is reproducible 100 percent of the time, your antivirus software may not be the cause. There
can be other causes for this error. Try creating a simple ASP.NET test application to
isolate whether the same error occurs for a Test.aspx page. If it does, then verify
that the required Access Control Lists (ACLs) are all in place for ASP.NET.
See ASP.NET Required Access Control Lists (ACLs):
http://msdn2.microsoft.com/en-us/library/kwzs111e.aspx
(http://msdn2.microsoft.com/en-us/library/kwzs111e.aspx)
Tip The %SystemRoot%\Assembly folder is the global assembly cache. You cannot directly use Windows Explorer to edit ACLs for this
folder. Instead, use a command prompt and run the following command:
cacls %windir%\assembly /e /t
/p domain\useraccount:r
Alternatively, prior to using Windows Explorer, unregister
Shfusion.dll with the following command to give permissions via the GUI:
C:\WINDOWS\Microsoft.NET\Framework\VersionNumber>regsvr32–u shfusion.dll
After setting permissions with Windows Explorer, re-register
Shfusion.dll with the following command:
C:\WINDOWS\Microsoft.NET\Framework\VersionNumber>regsvr32
shfusion.dll
Issue occurs because of missing permissions on a remote resource that the ASP.NET application is trying to access
When your ASP.NET application is accessing a remote resource like
Microsoft SQL Server or a Universal Naming Convention (UNC) share, there are many things that can go wrong. Also, many things may be
incorrectly set up on the remote resource. You'll need to troubleshoot those issues in order to get the resource working.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
891031Â
(http://kbalertz.com/Feedback.aspx?kbNumber=891031/
)
Common security issues when you access remote resources from ASP.NET applications
Your first step would be to see if you can connect
to the remote server through Windows Explorer.
- On the remote server, create a folder called Test. On
the Sharing and Security tabs of the Test folder, add your domain/account, and
also the process account that is used by your ASP.NET application, and give
them both Full Control.
Note Please see891031Â
(http://kbalertz.com/Feedback.aspx?kbNumber=891031/
)
for techniques or
workarounds to access remote resources from ASP.NET. - On the IIS server, log in with your domain/account, click Start, click Run, and then type the UNC share path of the remote server:
\\RemoteServerName\Test
If you are unable to get to this folder, then contact your Network
Administrator to fix this issue. Only then can your ASP.NET application access
the share. - Create a file called CreateUNCFile.aspx with the code below
and save the file in your application directory.
<%@ Page Language="vb" %>
<%@ Import Namespace="System.IO" %>
<html>
<head>
<title>Writing to a Text File</title>
<script runat="server">
Sub WriteToFile(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim fp As StreamWriter
fp = File.CreateText("\\<RemoteServerName>\Test\" & "test.txt")
fp.WriteLine(txtMyFile.Text)
lblStatus.Text = "The File Successfully created! Your ASP.NET process is able to access this remote share"
fp.Close()
End Sub
</script>
</head>
<body style="font: 10pt verdana">
<h3 align="center">Creating a Text File in ASP.NET</h3>
<form id="Form1" method="post" runat="server">
Type your text:
<asp:TextBox ID="txtMyFile" TextMode="MultiLine" Rows="10" Columns="60" Runat="server" /><br>
<asp:button ID="btnSubmit" Text="Create File" OnClick="WriteToFile" Runat="server" />
<asp:Label ID="lblStatus" Font-Bold="True" ForeColor="#ff0000" Runat="server" />
</form>
</body>
</html>
- Make sure that you modify <RemoteServerName> in the following line of code
fp = File.CreateText("\\<RemoteServerName>\Test\" & "test.txt") so that it reflects the name of your remote server. - Open Windows Internet Explorer and browse to
http://IISServerName/AppName/CreateUNCFile.aspx
from a client computer other than the IIS server.
- If the Test.txt file creates successfully, then your
ASP.NET application can authenticate to the remote resource.
- If file creation fails from an Internet Explorer client browser but works
if you browse to the same page from the IIS server itself, then it's likely
that you are running into a "Double Hop" scenario. If you are using custom built Web Parts to access remote resources that require user authentication and authorization, you will probably run into the "Double Hop" problem. In order to access your remote resource, you may need to supply the end user's credentials to the resource so that the output from the resource is limited to the data that the end user has permission to access.
The above steps assume that you have NTLM Authentication turned on in IIS. Basic Authentication does not use Kerberos.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
907272Â
(http://kbalertz.com/Feedback.aspx?kbNumber=907272/
)
Kerberos authentication and troubleshooting delegation issues
326985Â
(http://kbalertz.com/Feedback.aspx?kbNumber=326985/
)
How to troubleshoot Kerberos-related issues in IIS
For more information on IIS authentication methods,
see
the following Microsoft Developer Network (MSDN) Web site:
Tip If you can connect to the remote UNC share but you can not connect to
the remote server that is running SQL Server from the ASP.NET application, then you might have to check or
set the Service Principal Names (SPNs) for SQL Server. Try enabling only Basic Authentication for your
application in IIS and see if you are able to connect to the remote server that is running SQL Server.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
319723Â
(http://kbalertz.com/Feedback.aspx?kbNumber=319723/
)
How to use Kerberos authentication in SQL Server
316989Â
(http://kbalertz.com/Feedback.aspx?kbNumber=316989/
)
Error message when you create a trusted data connection from ASP.NET to SQL Server: "Login failed for user: 'AccountName'"
Tip It's never recommended to use mapped drives to connect to a remote
resource because drive mappings are an extension of the
net use command and are created on a per-user basis. The preferred method
of accessing content for the Web server that exists on a remote computer is to
use shares that follow the UNC.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
257174Â
(http://kbalertz.com/Feedback.aspx?kbNumber=257174/
)
Using mapped drives with IIS
Code Access Security (CAS) related issue
Error messages in ASP.NET are detailed and, more often than not,
tell you exactly what the problem is. In some cases, FileMon or RegMon may not
capture anything useful. Let's take a look at one such scenario.
Scenario
While trying to browse an ASP.NET application, it fails with
a generic error such as the following infamous error:
Collapse this imageExpand this image
The event log shows:
Event Type: Error
Event Source: ASP.NET 1.1.4322.0
Event Category: None
Event ID: 1088
Date: 10/11/2006
Time: 10:54:04 PM
User: N/A
Computer: ComputerName
Description:
Failed to execute request because the App-Domain could not be created. Error: 0x8013150a
When an ASP.NET application domain is created, ASP.NET reads
the value specified for the level attribute of the trust configuration element,
creates an instance of the
AspNetHostingPermission class with the specified
Level attribute, and then adds the class to the permission set for the
application domain. You will see the above error if the trust levels are
incorrectly configured or modified. For more information, see
"ASP.NET Trust
Levels and Policy Files" at the following MSDN Web site:
To resolve this issue, you can try
this
Tip in the "Issue occurs because of missing permissions on a local resource that the ASP.NET application tries to access" section, but do not get
disheartened if the application does not work with an Administrator or SYSTEM
account. You need to check to see if the issue can be caused by Code Access Security.
This can easily be done by turning off Code Access Security using the
Caspol.exe utility.
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322>caspol -s off
Microsoft (R) .NET Framework CasPol 1.1.4322.573
Copyright (C)
Microsoft Corporation 1998-2002. All rights reserved.
Success
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322>
Once
you have run
caspol –s off, reset IIS and try to browse the application. If
this step works, you then need to check the permission set for the code groups.
You can access the code groups in the Microsoft .NET Framework
VersionNumber
Configuration tool that is found in Administrative Tools.
In this scenario,
the
Permission Set for the
My_Computer_Zone code group was set to
Nothing.
Changing it to
Full Trust resolved the issue
Note To access the
My_Computer_Zone code group, follow these steps:
- In Control Panel, double-click Administrative tools.
- Double-click Microsoft .NET Framework VersionNumber Configuration.
- Double-click Runtime Security Policy.
- Double-click Machine.
- Double-click Code
Groups.
- Double-click All_Code.
- Double-click My_Computer_Zone.
Tip Remember to run
caspol –s on to turn on CAS once you have fixed
the issue.
For more information, see ASP.NET Code Access
Security:
http://msdn2.microsoft.com/en-us/library/87x8e4d1.aspx
(http://msdn2.microsoft.com/en-us/library/87x8e4d1.aspx)
There
are numerous other causes for the "Server Application Unavailable" error
message. The event log is your best bet to get more details on the cause of
your issue.
IIS-related errors
The IIS logs are very useful in cases of IIS authentication-related errors. A common scenario is when the user would typically see the following:
Collapse this imageExpand this image
What you need to look for is
the status and sub status codes for this particular error.
2006-10-12 22:47:28 W3SVC1 65.52.18.230 GET /MyAPP/login.aspx - 80
MyDomain\UserID_91 65.52.22.58
Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+2.0.50727;+InfoPath.1)
401 3 5
We see a 401 with the sub-status 3, which indicates
"Unauthorized due to ACL on resource."
This indicates missing NTFS
permissions on a file or folder. This error may occur even if the permissions
are correct for the file that you are trying to access, but the default
permissions and user rights may be missing on other SYSTEM and IIS folders. For
example, you may see this error if the IUSR_ComputerName account does not have
access to the C:\Winnt\System32\Inetsrv directory.
For more information about IIS status codes, click the following article number to view the article in the Microsoft Knowledge Base:
318380Â
(http://kbalertz.com/Feedback.aspx?kbNumber=318380/
)
Description of Microsoft Internet Information Services (IIS) 5.0 and 6.0 status codes
812614Â
(http://kbalertz.com/Feedback.aspx?kbNumber=812614/
)
Default permissions and user rights for IIS 6.0
271071Â
(http://kbalertz.com/Feedback.aspx?kbNumber=271071/
)
How to set
required NTFS permissions and user rights for an IIS 5.0 Web server
Tip Click
Start, click
Run, and
then type
logfiles to open the folder that contains the
IIS logs. Alternatively, on the properties page for your Website in IIS, click the
WebSiteName tab, and under
Active log format, click
Properties to see the Log file
directory and name.
The other thing of interest here is
the status code 5. You can use the
net helpmsg command to
get more info on this status code:
C:\Documents and Settings\User>net helpmsg 5
Let's try another common status code, code 50:
C:\Documents and Settings\User>
net helpmsg 50The request is not supported.
Tip Whenever you get another generic infamous "500 Internal Server
Error" message, then it's a good idea to disable friendly HTTP error messages, so that you receive
a detailed description of the error. Don't forget to look in the event viewer
as it may also contain more information.
For more information about how to disable friendly HTTP error messages, click the following article number to view the article in the Microsoft Knowledge Base:
294807Â
(http://kbalertz.com/Feedback.aspx?kbNumber=294807/
)
Turn off the Internet Explorer 5.x and 6.x "show friendly HTTP error messages" feature on the server side
The idea is to use all the logged information
available to get maximum details on the problem at hand.