Custom 401 page in IIS with ASP.NET - asp.net

I have an internet facing ASP.NET website which I want to secure via Windows Authentication. I set my web.config file as:
<system.web>
<authentication mode="Windows" />
<authorization>
<allow users="*"/>
<deny users="?"/>
</authorization>
I have then disabled Anonymous Access and enabled Windows Authentication in IIS 7.5.
This results in the prompt box being displayed for my Windows credentials, however clicking 'Cancel' gives me a standard 401 error page. I would like to display a static HTML file in place of this message, however I've not been able to get it working and I've tried a combination of various settings such as:
<httpErrors errorMode="Custom" existingResponse="Replace" lockAllAttributesExcept="errorMode"> <error statusCode="401" prefixLanguageFilePath="c:\inetpub\custerr" path="MyCustom401.htm" /> </httpErrors>
and
<customErrors mode="Off" defaultRedirect="ErrorPage.aspx">
<error statusCode="401" redirect="MyCustom401.aspx" />
</customErrors>
What I would like to happen is that anyone entering the correct Windows credentials can carry onto the website as normal, but those with invalid or details to see the custom HTML page.
Can anyone point me in the right direction?
Thanks!

One thing to make sure is that you are allowing anonymous users access to the path where the error files are included otherwise they won't get the error page. For example here is a configuration file that should give you the intended results if your error files are in a directory (errors). First it disables anonymous access for all the site, but then opens it for the "errors" folder:
<configuration>
<system.webServer>
<security>
<authorization>
<add accessType="Deny" users="?" />
</authorization>
</security>
<httpErrors errorMode="Custom">
<error statusCode="401" subStatusCode="2" path="/errors/unauthorized.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<location path="errors">
<system.webServer>
<security>
<authorization>
<clear />
<add accessType="Allow" users="*" />
</authorization>
</security>
</system.webServer>
</location>
</configuration>

Related

Anonymous authentication using generic asp.net handler (*.ashx)

I have an asp.net webforms application that has windows authentication enabled. I need to enable anonymous authentication on a folder “Test” in the website which contains images . I did that by adding
<location path="Test">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true"/>
</authentication>
</security>
</system.webServer>
Now any requests to images in Test folder is unauthenticated and everything works as expected until I introduced a generic handler for this folder which fetches files from the backend storage if the file is not found in the “Test” folder and boom it broke! Anonymous authentication doesn’t work anymore. Updated web.config file below -
<location path="Test">
<system.webServer>
<handlers>
<add verb="*" path="Test" requireAccess="None" name="Handler1" type="WebApplication1.Test.Handler1, Anonymous" />
</handlers>
<security>
<authentication>
<anonymousAuthentication enabled="true"/>
</authentication>
</security>
</system.webServer>
I inspected the request using fiddler and it returns HTTP/1.1 401 Unauthorized message if I have the handler section in config but if I remove the handler section from config everything just works fine and I can see the valid response in fiddler. Any insight into what could be wrong here?
Finally I was able to resolve it myself by modifying the location configuration as shown below by adding system.web to allow all users
<location path="Test">
<system.webServer>
<handlers>
<add verb="*" path="Test" requireAccess="None" name="Handler1" type="WebApplication1.Test.Handler1, Anonymous" />
</handlers>
<security>
<authentication>
<anonymousAuthentication enabled="true"/>
</authentication>
</security>
</system.webServer>
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>

Deny all files in a directory, via web.config setting

As a test, I'm trying to use the web.config to control security in the following ways:
Deny access to all files in a directory, except for a specific file
Allow access to all files in a directory, except for a specific file
So I set up the web.config as follows:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- Deny access to all files in a directory, except for a specific file -->
<location path="NonAccessibleDirectory">
<system.web>
<authorization>
<deny users="?"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="NonAccessibleDirectory/AccessibleFile.html">
<system.web>
<authorization>
<allow users="?"/>
<allow users="*"/>
</authorization>
</system.web>
</location>
<!-- Allow access to all files in a directory, except for a specific file -->
<location path="AccessibleDirectory/NonAccessibleFile.html">
<system.web>
<authorization>
<deny users="?"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
As expected:
If I browse to the non accessible directory and do not specify a file, I get access denied
If I browse to the accessible directory and do not specify a file, I can see the list of files
The problems I'm having are:
If I browse to the non accessible directory and specify a file, I can view it, and I would have expected not to be granted access
If I browse to the accessible directory and specify a file I have denied access to via the web.config, I can still view it, and I would have expected not to be granted access
Amy I configuring things wrong?
You may be running in to the difference between ASP.NET URL Authorization and IIS URL Authorization. A detailed summary on this is at http://www.iis.net/learn/manage/configuring-security/understanding-iis-url-authorization#Differences
Briefly, what happens with ASP.NET by default with web.config is that it only apply the allow and deny rules to files handled by the managed handler.
Files such as .txt and .html files are handled by IIS and not ASP.NET, so the authorization rules aren't applied to them.
You can test this out by adding this to your main web.config to use the IIS version.
<system.webServer>
<modules>
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
</modules>
</system.webServer>
I tested this with your same security and same directories and files, and all appears to work
A more complete version if you use other authentication methods such as forms could be this
<system.webServer>
<modules>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<remove name="DefaultAuthentication" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</modules>
</system.webServer>

IIS Keeps Redirecting to Login.aspx when I set Default.aspx as default page

IIS Keeps Redirecting me to Login.aspx when I set Default.aspx as default page. In my dev environment its working fine, I get to the right page, but as soon as I publish and try from the IIS server login.aspx always comes first.
I have made sure anon users are allowed :
<location path="Default.aspx">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
And its set as default url (further down the config) :
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="Default.aspx"></forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
I even set the default page in IIS, but it resets it every time on publish.
Try adding the Authenticated User to the security property of the web folder in IIS. Give the modify privilege (Read, Write, Modify, List Folder Content, Read & execute) to this user.
This of course should only be a temporary situation to verify that you have a permission issue. You should consider setting proper permissions for site users.
//Peace
I spent about 6 hours debugging the issue. Our website was working fine, and suddenly it started redirecting to login page instead of default page (unauthenticated). Our web.config included all authentication/authorization settings correctly.
<authentication mode="Forms">
<forms name="MyAuth" path="/" loginUrl="login.aspx" protection="All" timeout="30" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
<system.webServer>
<defaultDocument>
<files>
<clear />
<add value="default.htm" />
</files>
</defaultDocument>
...
</system.webServer>
<location path="default.htm">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
...
SOLUTION: You need to remove Extensionless URL feature from your website.
Ref: https://support.microsoft.com/en-us/help/2526854/users-may-be-redirected-to-the-login-page-of-an-asp-net-4-application
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
After the fix, the website was back to normal.

IIS 7 Basic authentication location issue

I have a website on IIS 7 using Basic authentication. There are some pages that must be public. I added an this exception in a location element in the web.config and it looks like this:
<location path="Errors">
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="*" />
</authorization>
</security>
</system.webServer>
</location>
However, if I try to access some files from that folder, I get this error:
HTTP Error 401.2 - Unauthorized You are not authorized to view this
page due to invalid authentication headers. Detailed Error Information
Module IIS Web Core Notification AuthenticateRequest Handler
StaticFile Error Code 0x80070005 Requested URL
http://srv/Errors/error401.htm Physical Path
D:\www\MyApp\Errors\error401.htm Logon Method Not yet determined
Logon User Not yet determined
How can I have Basic Auth over my site, but allow everyone access on the Errors directory?
IIRC, "?" is for anonymous users... So turn on Anonymous authentication aswell and put this in your web.config... Hope it works for you...
IIS7
<location path="Errors">
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="*" />
</authorization>
</security>
</system.webServer>
</location>
IIS6 (or IIS7 Classic mode)
<location path="Errors">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
EDIT
I'm not sure removing the authenticatied users (*) for errors is a good idea, though... Authenticated users can get errors, too... Show them some love... ;)
EDIT 2 (Changed for Classic mode in IIS7)

ASP.NET login control hijacks my 404

I have implemented the standard Login control and everything works fine.
However when i enter an invalid URL it gets redirected to the Login page.
e.g.
mywebsite.com/xxx correctly gives a 404
but
mywebsite.com/xxx.aspx causes a redirect to the login page
I am using ASP.NET 3.5 on Windows Server 2008.
I have set up the web.config with the following
and also
<httpErrors existingResponse="Replace">
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="403" path="/xyz/NoAccess.htm" responseMode="Redirect" />
<error statusCode="404" path="/xyz/FileNotFound.htm" responseMode="Redirect" />
<error statusCode="500" path="/xyz/FileNotFound.htm" responseMode="Redirect" />
</httpErrors>
Authentication is via webforms
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="~/External/SomeView.aspx"></forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
So it seems the login page is hijacking my 404.
How do i make http://www.mywebsite.com/xxx.aspx return a 404 instead of redirecting to the login page?
I think you need to make your 404 page accessible to all users - try adding this to your web.config:
<location path="/xyz/FileNotFound.htm">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
No, the login page is not hijacking the 404 result - but you're returning a 403, on which you have told the authentication module to redirect to the login page.
I don't know enough about the inner workings of the errors configuration section in web.config, but try switching the order around:
<!-- Notice that the 404 rule is before the 403 rule -->
<error statusCode="404" path="/xyz/FileNotFound.htm" responseMode="Redirect" />
<error statusCode="403" path="/xyz/NoAccess.htm" responseMode="Redirect" />
<error statusCode="500" path="/xyz/FileNotFound.htm" responseMode="Redirect" />
If that doesn't work, change your access rules to allow access to xxx.aspx, by removing
<deny users="?" />
since that requires all users to log in before they can access anything. (? matches any anonymous, that is non-logged-in, user...)

Resources