IIS URL Authorization check in ASP.Net - asp.net

I have an ASP.Net web forms app running under IIS 7+
The entire app is currently secured using Windows Authentication and URL Authorization, configured in the web.config via IIS. The .NET doesn't care who the user is, there are no profiles or roles or anything at the moment.
<system.web>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AppXUsers" />
<deny users ="?" />
</authorization>
</system.web>
I wish to add an additional page (in a subfolder), which will be accessible to subset of users, so I would modify the web.config like so:
<location path="mySubFolder">
<system.web>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AppXPowerUsers" />
<deny users ="?" />
</authorization>
</system.web>
</location>
The client is free to then add or remove AD groups as they see fit.
However, as it stands users who are in the AppXUsers group but not in the AppXPowerUsers group still get shown links to the pages in mySubFolder. When they click the links they get access denied as it should be.
Is there any way I can detect whether or not the current user has access to "mySubFolder"?
I feel it would be a bit overkill to introduce User/RoleManagement at this stage - the application has no need to store any information relevant to users and it doesn't care who the user is beyond "can they access this page or not", which is currently handled at the IIS stage.

Take a look at this: http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx
which is referenced here:
Determine if user can access the requested page?
UrlAuthorizationModule.CheckUrlAccessForPrincipal requires that the authorization rules are set in <system.web><authorization>
If you're introducing this into your web.config, though - why are you reluctant to use it in code?
Another way to check would be:
Context.User.IsInRole("somerole")

Related

Anonymous on the entire site except for one page using asp.net

I would like to have anonymous access for an entire asp.net site except for one page. On that one page, I would still like everyone to access the page but I would like to retrieve their username. Here is what I have so far:
In the web.config, system.web section I am requesting windows authentication:
<authentication mode="Windows">
</authentication>
Then I am specifying the location that I would like to force windows authentication:
<location path="forceWindowsAuth.aspx">
<system.web>
<authorization>
<!-- will deny anonymous users -->
<deny users="?"/>
</authorization>
</system.web>
</location>
However this is still not working. It is denying everyone from viewing forceWindowsAuth.aspx with the message "Access is Denied"
The IIS site is configured for both anonymous and windows auth. I just cannot figure out how to force windows auth on one page only. Thank you before hand for your help.
The problem is whether you have seen "Allow all user" rule inherited from root level. As you can see I only have a deny rule for anonymous rule, but it will also inherit the allow all users rule. So it will promise only anonymous user will be blocked in this page and other user will not be blocked.
If there is only one "deny anonymous user", other user will never be able to view this page. If you don't set either deny or allow for a user, IIS will block the user by default.
Edit:
You can fix this by modifying the web.config like this.
<location path="forceWindowsAuth.aspx">
<system.webServer>
<security>
<authorization>
<clear/>
<add accessType="Allow" users="*" />
<add accessType="Deny" users="?" />
</authorization>
</security>
</system.webServer>
</location>

Url Authorization with MVC and ASP.NET Identity

I want to secure specific folders and resources in my application that are outside of the routes for my mvc application. I want these resources to only be available to authenticated users (which role is not of concequence as long as they are authenticated).
Initially it seemed that the UrlAuthorizationModule would be the answer. I followed this article, Understanding IIS 7.0 URL Authorization, and I can get the module to work in the sense that it responds to the configuration elements in the web.config.
My current problem is that I think it is enacting the rules based on the anonymous user in IIS and not the authenticated user in asp.net identity.
Test Environment
I use a standard html file for testing instead of trying to load a script as this would also be loaded outside of the MVC pipeline.
In Visual Studio 2015.
New default .net 4.6.2 web project
MVC template
Authentication = Individual User Accounts
IIS 8 (for testing outside Visual Studio)
Authentication -> Anonymous Authentication (enabled)
Add to web.config
<configuration>
...
<location path="Data">
<system.webServer>
<security>
<authorization>
<clear/>
<add accessType="Deny" users="*"/>
<add accessType="Allow" users="?"/>
</authorization>
</security>
</system.webServer>
</location>
...
</configuration>
Add to folder structure
/Data/Protected.html // this file just has some basic Hello World content to display so you can see if it is loaded or not.
Observed Results
With this configuration everything in the Data path is always denied, it does not matter if the user is authenticated or not.
The same is true if I switch the 2 lines for Deny and Allow in the web.config.
If I completely remove the line with Deny then access is always allowed even when the user is not authenticated.
If I add a role and use roles with the role name instead of users attribute the role is also completely ignored.
Now What?
What am I missing? How can I get the Url Authorization module to work with MVC/WebAPI and ASP.NET Identity Individual user accounts or is this simply not doable?
I am open to alternative ideas as well, maybe the answer is to write a custom HttpModule or HttpHandler?
Side notes
Why & Specifics
These resources are javascript files, in short only a portion of the scripts should be available to unauthenticated users. There are 2 directories in the root, one for the authenticated part of the app and one for the non-authenticated part of the app. The reason for this has nothing to do with user authorization or security in the application, it is to limit the exposed surface area of the application to non-authenticated requests.
[TL;DR;]
Go to "Complete root web.config" section to see the needed web.config setup.
Test this in incognito-mode to prevent browser caching issues!
And use Ctrl+F5 because scripts and html files get cached.
First deny access to all anonymous users in the root web.config.
<authorization>
<deny users="?"/>
</authorization>
The web.config here allows one folder to be publicly accessible. This folder, in my example here, is called css and sits in the root of the MVC application. For the css folder I add the following authorization to the root web.config:
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
You can add more of these location paths if you want more public folders.
While all other files will not be accessible until the user logs in, the css folder and its contents will always be accessible.
I have also added a static file handler to the root web.config, This is critical as you want the request to be managed by the asp.net pipeline for the specific file type(s):
<handlers>
<add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
Complete root web.config
<system.web>
<authentication mode="None" />
<authorization>
<deny users="?"/>
</authorization>
<compilation debug="true" targetFramework="4.6.2" />
<httpRuntime targetFramework="4.6.2" />
</system.web>
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
</modules>
<handlers>
<add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
</system.webServer>
ASP.NET by default will only apply the allow and deny rules to files handled by the managed handler. Static files are not managed by the managed handler.
You could also set: (Don't do this, if not really needed!)
<modules runAllManagedModulesForAllRequests="true">
With runAllManagedModulesForAllRequests="true" all the HTTP modules will run on every request, not just managed requests (e.g. .aspx, ashx). This means modules will run on every .jpg ,.gif ,.css ,.html, .pdf, ... request.
One important thing
You don't have to add the UrlAuthorizationModule to the modules section as it is already part of the ASP.NET pipeline. This means, it will run only for managed files, not static!
If you now remove and then re-add the UrlAuthorizationModule to the modules section, it will run under precondition "integratedMode" and not under "managedHandler" anymore! And will therefore have access to static files.
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
If you set the precondition to managed:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />, then the UrlAuthorizationModule will not restrict access to static files anymore.
You can test this by accessing a script file in the scripts folder successfully while being logged out. Hit Ctrl+F5 to make sure you get a fresh copy of the script file.
Difference between ASP.NET UrlAuthorization <--> IIS URL Authorization
It is important to keep in mind that the managedHandler precondition
is on the ASP.NET UrlAuthorization module. The precondition tells you
that the URL authorization module is invoked only when the code that
handles the request is mapped to managed code, typically an .aspx or
.asmx page. IIS URL Authorization, on the other hand, applies to all
content. You can remove the managedHandler precondition from the
ASP.NET Url Authorization module. It is there to prevent a performance
penality you have to pay when every request (such as a request to
.html or .jpg pages) would have to go through managed code.
P.S.: Some web.config attributes are case sensitive!

ASP.NET Unable to use custom Window group as a Role

I want to use a local group to restrict access to an ASP.NET web application to local users.
I've created a Windows group (TestLocalGroup) and Windows user accounts and assigned them all to the new group. The group and accounts are on the IIS7 web server.
In my web.config, I can properly restrict access to specific users by defining the following settings...
<authentication mode="Windows" />
<authorization>
<allow users=".\TestLocalUser1,.\TestLocalUser2" />
<deny users="*" />
</authorization>
But I can't seem to get it to work for the group. This code won't allow my group members access...
<authentication mode="Windows" />
<authorization>
<allow roles=".\TestLocalGroup" />
<deny users="*" />
</authorization>
I don't have any "roleManager" section. Do I need that?
Am I missing something? It seems like it should just work.
There were two problems.
1) It turns out that I had a different roleManager enabled on a parent web.config.
<roleManager enabled="true" defaultProvider="SqlRoleManager">...
For my site I had to clear the roleManager to get the windows roles to work again.
<roleManager enabled="false" />
2) As I was adding my users to the groups, there didn't appear to be any immediate effect. I logged on and off as suggested by mellamokb (Thank you!). That didn't make any difference, but it did point me to the correct solution; recycling my web site. I assume there is some timed credential cache and recycling the web site will clear it.
In my case,,, I have to delete roleManager... from my web.config.

<authorization> can protect pages?

Can I use <authorization> to protect webforms from being accessed if a person does not have a specific role?
I tried this:
<authentication mode="windows" />
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
but if the role Admin is not available then I can still visit the page by typing in the URL. How can I protect this page?
I read the documentation on MSDN (ASP.NET Authorization).
I also put the UrlAuthorizeModule extra in the web.config to make sure that it gets hit.
Best to read this: ASP.NET Authorization
It explains how to set the allow/deny elements for users and roles.

Forms authentication for xml files

I was wondering if you could protect xml files through forms authentication in ASP.NET 3.5.
I have some licensekeys that are found online, but you shouldn't be able to download them unless you are logged on.
For aspx pages this works automatically but not for xml files.
Place the xml files in a certain folder, add web.config to this folder containing:
<configuration>
<system.web>
<authorization>
<deny users="?"/>
<allow roles="admin"/>
</authorization>
</system.web>
</configuration>
Change the '?' (which means anonymous users - i.e. not logged in users) to '*' in order to deny all users (the server will have access [e.g. via Server.MapPath etc.]).
Respectively you can play with the roles or remove this line.
Also, consider that in the web.config file you can deny and allow specific extensions as follows:
<system.web>
<httpHandlers>
<remove verb="*" path="*.xml" />
<!--or-->
<add verb="*" path="*.xml" type="System.Web.HttpForbiddenHandler" />
</httpHandlers>
</system.web>
Please don't rely on this last snippet till you make sure what are your needs.
You can find out more on Http Handlers, or take a look at How to: Register HTTP Handlers.
I also noticed someone asked a similar question here, you may find it helpful.
Hope you to find your quickly find your solution, good luck!

Resources