How to use windows authenication while having an anonymous page - asp.net

I have the following structure
login.aspx
reallysecure/homepage.aspx
I'm trying to allow anonymous access to login.aspx and windows authenication to reallysecure/homepage.aspx
My IIS auth is configured to only have anonymous enabled.
Here is my web.config
<?xml version="1.0"?>
<configuration>
<location path="reallysecure">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true"></windowsAuthentication>
</authentication>
</security>
</system.webServer>
When I navigate to login.aspx everything works as intended. However when I redirect to reallysecure/homepage.aspx i get the following error:
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
81: <authentication>
82: <windowsAuthentication enabled="true"></windowsAuthentication>
83: </authentication>
How do i setup the web.config and IIS to accomplish what i need?
Thanks!

It's a question of authentication vs authorization. Windows authentication should be set at the root level, and should be used for the entire site. But at the root level, you'll specify that anonymous users are allowed, and in "reallysecure" specify that anonymous users are not allowed.
So, instead of the authentication section in the location, set up an authorization section:
<authorization>
<deny users="?"/>
</authorization>
(? == anonymous)
And, at the root level, it should be:
<authorization>
<allow users="*"/>
</authorization>
(* == all users, including anonymous)

Related

How to make IIS authorize requests based on Windows user name or group membership?

I have a legacy web app hosted using PHP by IIS. Access to some of the directories of that app is restricted using the following configuration in web.config of the root directory. That makes the Windows username available as REMOTE_USER, so that the app can map that username into an individual database to check authorization. This works and MUST NOT be changed.
<location path="lsgprog/bibliothek/adm">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
Access to some other directories is restricted as well and as well using credentials provided by Windows. So those other directories have anonymousAuthentication disabled and windowsAuthentication enabled as well. The difference is 1. that those settings are made in the GUI of IIS and 2. that authorization is actually checked against the file system. This means that the directories simply have read access only for some special groups of users, those groups and users are maintained by some Active Directory and because the app uses Windows auth, things simply work. Users authenticate at their Windows, open Internet Explorer, request the restricted parts of the site, IIS gets the username, group membership etc., checks access to the restricted directories in the file system and grants or denies it.
All of that is configured manually using the GUI of IIS and I want to migrate that to web.config. Enabling Windows auth for some directories is already documented above, what I'm missing is how to allow/deny access to users and groups, which is the file system part. I've already found the element authorization, which pretty much looks like what I want, but whatever I try doesn't work.
<location path="lsgprog/vfristen">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
<system.web>
<authorization>
<deny users="*"
roles="*"
verbs="GET,HEAD,POST" />
</authorization>
</system.web>
</location>
My expectation was that the above is enough to DENY access to all users, but that doesn't work and any approach based on ALLOW doesn't as well. I hoped that users and roles could simply be mapped against the username and group names of the currently requesting user. What I don't want is form based authorization or converting directories to "apps" or anything that needs to be done outside of web.config.
So, is what I'm trying to do possible at all and if so, how? Thanks!
In this scenario there are multiple options, first - try and add a web.config file to the folder that needs to have its' own permissions e.g. under lsgprog/vfristen, the minimum web.config example which will deny all users access:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
Why does it work - IIS looks at each folder structure for web.config files, in this case the child will overwrite the parent but only the nodes that are inside the child - meaning it will preserve all other settings from the parent (root) web.config:
Make application and directory-specific configuration settings in an ASP.NET application
Although the documentation above is for ASP.NET it applies at the IIS level as well.
Second option to try - since the question mentioned the root of the project is lsgprog then this setting in web.config:
<location path="lsgprog/vfristen">
Should be changed to (remove the root folder of the project from the path):
<location path="vfristen">
Finally third option which could also work is overwriting it at the Machine.config level as mentioned in the above document:
Use the location element in the Machine.config file
When the allowOverride attribute is false, the Web.config files in the web application directories can't override the settings that you specified in the element. This is a useful setting in environments where you must restrict application developers in how they configure a web application. The following example shows a part of a Machine.config file that requires authentication to access the MyApp application on the default Web site and that can't be overridden by settings in a Web.config file:
Machine.config
<configuration>
<location path="Default Web Site/MyApp" allowOverride="false">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
</configuration>
You could try to add the below code in your site web.config file:
<location path="foldername">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
<location path="foldername/page1.php">
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="DOMAIN\ADGROUP" />
<add accessType="Deny" users="*" />
</authorization>
</security>
</system.webServer>
</location>
Edit: need to install the URL Authorization in iis to make this rule work.
https://learn.microsoft.com/en-us/iis/manage/configuring-security/understanding-iis-url-authorization

How to allow anonymous user access to virtual directory

I am currently preventing anonymous users access to my root application.
/web.config
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
But am allowing anonymous access to public resources (Images, CSS, etc.):
<location path="Images">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Now, I would like to add a virtual directory which should be accessible to anonymous users. I added a configuration based on the Images path, but whenever I try to access that location, I get redirected to the login page with the ReturnURL set to the virtual directory.
<location path="virtualDirectory">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
In addition, I tried to specify the global authorization within my virtual directory's web.config but get an error saying I can only have that once
/virtualDirectory/web.config:
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
How can I allow anonymous access to a virtual directory when my root application is preventing anonymous access?
In your global web.config encapsulate the
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
with
<location path="." inheritInChildApplications="false">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
It means - authorization is enforced only in root app, not for the child apps.
Some notes.
The asterisk mark (*) represents all identity.
The question mark (?) represents the anonymous identity.
So ideally, you don't need to set to allow authentication for the anonymous user for your virtualDirectory in the global web.config.
Go to IIS, under your Virtual Directory > select Authentication > Enable Anonymous Authentication.
Refer
ASP.NET Authorization
How to: Create and Configure Virtual Directories in IIS
In your global web.config remove
<location path="virtualDirectory">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Then go to IIS manager and
In the Virtual directory Home area, double-click Authentication
Right-click Anonymous Authentication, and then click Enable
Your authorization rules looks good. The last error you are getting is because you can have authorization section (in fact any section) only once per folder/file/path. So either have it globally i.e. under <location path="virtualDirectory"> or only in web.config of Virtual Directory. Having it in both places will give you an error. What is authentication set at Virtual Directory.
Make sure anonymous is enabled along with the allow authorization rule.
(IIS Manager ->Sites -> your specific site->virtual directory-> in the central pane Authentication )
Also in IIS GUI there are ASP.NET Authorization rules (the one you are using currently) and IIS Authorization rules. Make sure there aren't any deny IIS Authorization rules.

allow anonymous access to .well-known directory

please bear with me: i am pretty new to all of this
i am working on integrating openid connect with a pair of applications developed by the company.
we are using custom/company specific openid connect libraries that are, i think, essentially wrappers around Microsoft.Owin.Security.OpenIdConnect and Owin.Security.OpenIdConnect.Server
in the idP application web.config, we have something like:
<location path="." inheritInChildApplications="false">
<authentication mode="Forms">
<forms loginUrl="~/Login" name="{....}" protection="All" path="/" slidingExpiration="true" requireSSL="false" defaultUrl="~/Home" cookieless="UseCookies" />
</authentication>
<authorization>
<deny users="?" />
<!-- denies anonymous users to all pages, except those defined under location nodes -->
</authorization>
</location>
plus a bunch of location nodes to allow/deny access to specific pages/resources
the problem is that when the openid connect stuff tries to access /.well-known/openid-configuration when the user is not logged in (or, it seems in the process of logging in),
the response is a 302 redirect to the login page
obviously this is causing problems when a JSON response is expected
i have tried adding a location node to the web.config:
<location path= "~/.well-known/openid-configuration">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
(i also tried with path = "~/.well-known")
but i am still getting redirected to the login page
to be clear, there is no actual directory /.well-known in the idP application; the file seems to be constructed somewhere in Owin.Security.OpenIdConnect.Server.
the file seems to be constructed somewhere in Owin.Security.OpenIdConnect.Server
Yes, it is.
Try calling app.UseStageMarker(PipelineStage.Authenticate) immediately after registering the OIDC server middleware to prevent ASP.NET from applying the authorization policies before it has a chance to be invoked:
app.UseOpenIdConnectServer(options => {
options.AllowInsecureHttp = true;
});
app.UseStageMarker(PipelineStage.Authenticate);
Note that you shouldn't need an exception for ~/.well-known/openid-configuration in your web.config when using app.UseStageMarker().
I'm fairly new too but I think you a path to a .aspx page in the location and the rest is inherited.Just change deny to allow users with the asterix. Also make sure the web.config is in the directory. Sounds like you do but in well-known should be the web.config with allow all users.
<?xml version="1.0"?>
<configuration>
<location path="Manage.aspx">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
</configuration>

Access is Denied - 401.2: Unauthorized Error

I have an ASP.NET website hosted on IIS 7.5 as below:
I have "customwebsite.com" as the website and in it I have two Web Applications - uk & us - so that I can access these application as customwebsite.com/uk & customwebsite.com/us.
customwebsite.com directory does not have any web.config and have only two folders for web application us and uk.
Both us and uk web application have their individual web.config and have Form Authentication specified as below:
<authentication mode="Forms">
<forms loginUrl="/static/login.aspx" name="login" timeout="20"/>
</authentication>
<authorization>
<deny users="?" />
</authorization>
At this path: /static, there is a web.config with following content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</configuration>
When I hit the root URL for us application, the Website loads correctly but if I loads from uk, I got the error as below:
I have checked the Folder Security, and all the required users have been granted permission and are same for both us and uk applications.
I have checked the IIS logs and below is the response codes of the request in case of failure: 401 0 0 1519 296
Can someone help me resolving this issue.
Got it resolved.
There was two more folders where the redirection of /static/login.aspx happens.
We need to allow access to all such redirecting folders by having a web.config files in those folders with below content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</configuration>
Ran into this same error, but had a different resolution. In our case we had to set:
<machineKey compatibilityMode="Framework45" />
Details here:
http://ardalis.com/asp-net-shared-authentication-problem-solved
In our case we had an error on the login page that redirected to the an error page that the user did not have rights to see, so it redirected to the login page... cycle rinse repeat.
We removed all the controls from the UI, then added them back one by one until the page crashed. Then we could narrow down the controls that had an error.
And yes, we gave all users access to the error page.
Check below IIS setting
Authorization Rules -must contain only allow user setting not any any other rule ex. deny user rule.

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)

Resources