ASP.Net Provide Acceess/Browse Rights only to the Authenticated User - asp.net

On the root of my webservice application, I have a directory which contains some html and txt files. These files should be accessed only to the authenticated user. How can I achive this?
This is the follow-up of my question: ASP.Net Directory Security
I implemented HttpHandler as suggested by Shark on that post. It allows html and txt files to handle but I can't show these files to the authenticated user too.
Update: I solved this issue by checking session on the handler. While hosting this on the server I faced another problem. i.e. my custom handler was not getting called. I got the cause and solution for that issue on: http://msdn.microsoft.com/en-us/library/bb515343.aspx
Cause:
By default, Internet Information Services (IIS) passes requests for
only certain file types to ASP.NET to service. Files with file-name
extensions such as .aspx, asmx, and .ashx are already mapped to the
ASP.NET ISAPI extension (Aspnet_isapi.dll).
Solution:
To have IIS pass other file-name extensions to ASP.NET, you must
register the extensions in IIS.
Whole Story: http://www.naveenbhat.in/2012/06/directory-security-on-webservice-with.html

If you are using ASP.Net Security (Forms/Windows authentication), you can simply control it by web.config settings. Like so:
<system.web>
<authentication mode="Forms">
</authentication>
<location path="directoryPath">
<system.web>
<authorization>
<deny users="?"/> // this will deny access to anonymous users
</authorization>
</system.web>
</location>
</system.web>

Related

IIS 7.5 and making anonymous authentication/forms authentication play nicely together

I've got an ASP.NET MVC 4 application that I run under the site level of an IIS web site.
So the dir structure looks like this:
\IIS
\Site
\bin
\Content
\Views
The MVC 4 app uses Forms Authentication via Username and Password, but I have a requirement to lock down the full site and turn off anonymous authentication at the IIS level.
The goal of this requirement is to allow users only to land on a home page and logon page. The problem is if I turn off anonymous authentication then users can't even get to home or login.
Another thing we want to prevent a user from being able to go to /Content/Scripts/MyScript.js in their browser.
I'm using bundling so those file are there and don't get used by me besides when I bundle things up.
Is this even possible since IIS and MVC 4 auth are at completely different level? If it is possible what options do I have?
Chris Pratts answer is correct. You can successfully turn of anonymous authentication and let MVC4 handle all of that for you.
Make sure in your web.config you have the following
<modules runAllManagedModulesForAllRequests="true"></modules>
In your system.webserver section.
Another thing you can do is make use of the locations tags in IIS to prevent user access to different parts of the site.
For example, you could put this in your web.config
<location>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
This ensures that only authenticated users can access the site. You can then further refine this.
<location path="External">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Basically, now any request to /External will be allowed for all users (regardless of authentication). You will probably want to put all your scripts in here that you need unauthenticated users to access.
If there was a specific directory you didn't want anyone to access, you could do something like
<location path="/Content/Scripts">
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</location>
Now any access to that location will be prevented by default in IIS. Give that a try, it should satisfy your requirement to have the scripts available for bundling, but not accessible if someone browses directly to it.
I only halfway got what I wanted, but here is what I ended up doing. I have anonymous authentication enabled at the site level and used Forms authentication for specific controllers. This was how I originally had it so nothing changed here.
Since I am using bundles the users never really need to look at the .js so I used Request Filtering by file extension so block any .js and even .css I don't want exposed.
This works because the bundling doesn't make http requests to those files and the bundles themselves don't have the normal JavaScript and CSS file extensions.
You don't handle this at the IIS-level. You simply allow Anonymous Auth and then add [Authorize] to every controller. Then only on your home and login actions add the attribute [AllowAnonymous].
As to the second part of your question, you can't really stop this. MVC bundles on the fly, so it needs the actual files to be there. If they're never referenced, though, they're black holes: the user would have no way of knowing what file to request, so it's kind of security by obscurity.

ASP.NET web.config authorization settings ignored in subfolders

I'm using asp.net mvc 2 and vs 2008.
I'm trying to make website with forms authorization. When i'm trying to restrict access to some pages, i'm using asp.net administration tool. There i create rule, for example, to deny access to anonimous users to whole web site. Administration tool, as expected, adds following section in the root web.config file:
<authorization>
<deny users="?" />
</authorization>
When i do same thing in some subfolder, as example %ApplicationRoot%/View/Protected, administration tool, as expected too, adds web.config file in mentioned subfolder, with following code:
<configuration>
<system.web>
<authorization>
<deny users="UserName" />
</authorization>
</system.web>
Prime difference between theese files is that root web.config authorisation section has some effect(generally speaking, it works as planned - denies all unauthenticated users from whole website). But subfolder web.config authorisation section have no effect at all.
I found that then added to root config file, following code
<location path="Protected">
<authorization>
<deny users="UserName" />
</authorization>
</location>
does the work greatly - it, as planned, denies %UserName% acces to all views, located in %ApplicationRoot%/View/Protected Folder.
This behavoir is simmilar with cassini and iis, i tried both.
The main problem is that i need kind administration tool to do the work, so i'm asking for any help with issue - why doesn't authorisation section works when web.config is located in subfolder?
P.S. I tried to place incorrect code in between <authorization> and </authorization> in subfolder's web.config:
<authorization>
asdfg
</authorization>
No effect. Probably the whole section is ignored due to some issue?
P.P.S. Incorrect code out of the authorization section in the same file causes an error
Your problem is that your application is not a classical ASP.NET Web Forms application.
What you're trying to do would work perfectly in Web Forms, but not in MVC.
In MVC world when browser requests page /People/SmartList it's not necessarily that it would be shown the /People/SmartList.cshtml from your project. In fact, your project could not even have the /People/ folder at all. The view (.cshtml file) which will be shown by MVC engine is determined by routes. And that MVC routing engine doesn't look at all at your web.config files, when it accesses those .cshtml files. Now, you can see, why your web.conig files are ignored.
But you're still able to do the authorization. Instead of using web.config files you should use the [Authorize] attribute and apply it to appropriate controller's action methods, or even to a whole controller class.
[Authorize(Users="UserName")]
public ActionResult ShowRestrictedData()
...

Does web.config authorization work on files other than aspx?

I have ASP.NET application with forms authentication. It works well but I have one directory with olly .txt files (no aspx files) that I want users not to access (or only logged in users).
I added web.config to this directory:
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
EDIT:
This works only for .aspx files. It does not work for .txt files and similar. Users cannot browse this directory nor subdirectories however knowing .txt file name they can access it.
I tries IIS6 and IIS 7.5. On IIS6 .txt files are also restricted but on IIS 7.5 not so it may be IIS configuration issue.
Your question depends on the web server you are using. ASP.NET authorization works only with file types that are handled by ASP.NET. If you have IIS 5 or 6, this is normally not true for .txt files or even for .jpg, .gif and pure .html files, but only for aspx, asmx etc.
No problem if you have IIS7 and integrated mode, because ASP.NET is integrated and will be called for every type of file. So if you have IIS5 or 6 you have to register the mime types such as the aspnet.isapi is called for .txt files as well.
UPDATE:
The configuration of
<deny users="*">
locks out all users. It would work only in combination with allow, e.g.
<allow roles="administrators" />
<deny users="*">
like this all users but administrators will be locked out. If a user is authenticated but not adminstrator, he will be redirected to the login page.
The other option is to lock out anonymous users only:
<deny users="?">
Add location section to the web.config with appropriate settings location Element (ASP.NET Settings Schema)
If you use IIS 7+, then you can use the system.webServer/security/authorization http://www.iis.net/ConfigReference/system.webServer/security/authorization section, and have that automatically work for any kind of content in any pipeline mode.
IF you still want to use system.web seciton, then you will need to use Integreated Mode and do the changes that are mentioned in the modules to run for all content, but by far, the simplest is use system.webServer/security/authorization instead.

ASP.net quick and dirty authentication

I'm currently working on a page within one of my company's internet sites that is in response to some production issues we have. The page will be published with the rest of the web site to our DMZ, however I'd like to set-up some quick authentication so only users on our domain (assuming they access the site internally) can access the page. I'd like to use Windows authentication to do so.
Is there a quick way to accomplish this?
If I understand the question correctly, you want to enable security just on one page in your application - not the entire app.
Under IIS, you can manage the security settings on a page by page basis. In the IIS manager, pick the page, and change the security settings so that anonymous is off, and only Windows auth is accepted. You should get prompted for a login when you visit that page.
From Scott Gu's blog
To enable Windows Authentication
within an ASP.NET Application, you
should make sure that you have
“Integrated Windows Authentication”
(formerly called NTLM authentication)
enabled within IIS for the application
you are building. You should then
add a web.config file to the root
directory of your ASP.NET application
that contains an
section which sets the mode to
“Windows”.
You should also then add an
section to the same
web.config file that denies access to
“anonymous” users visiting the site.
This will force ASP.NET to always
authenticate the incoming browser user
using Windows Authentication – and
ensure that from within code on the
server you can always access the
username and Windows group membership
of the incoming user.
The below web.config file demonstrates
how to configure both steps described
above:
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
EDIT:
You can apply the auth settings to just a path in this way:
<location path="mypath.axd">
<system.web>
<authorization>
<allow roles="MyRole, AnotherRole" />
<deny users="*" />
<deny users="?" />
</authorization>
</system.web>
</location>
You can simply use Windows Authentication settings in IIS. Just turn off Anonymous Access in IIS and set your NTFS permissions on the Web folder to the users whom you want to have access to the site. Your IIS admin should be able to handle this quite easily.

Add authentication to subfolders without creating a web application

We have an existing publicly accessible web application with user controls, data access libraries, graphics, etc. We want to create a new secure section of the site that accesses some of the already existing resources.
Initially we created the new section of the site as a virtual directory which (we hoped) would allow us to access the parent site's resources. We added the appropriate location information to the base web.config (authentication and authorization) but we continue to see the following error "Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS."
In response to that error we created the directory as a new application. This allows us to authenticate properly but has the drawback of not being able to access any of the resources in the parent directory (since it's outside the application scope).
Is there any way to secure the new section of the site while at the same time utilize the already existing resources?
In your web.config file in the root of your site, if you add:
<location path="relativePathToDir">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
This is working for me using FormsAuthentication, the user gets redirected to the default login page if not authenticated
I typed up a summary since many were facing the same situation regarding subfolder authentication.
Subfolder Authorization
ASP.NET can only have a single
authentication mode for one
application.
The different
applications CANNOT share resource
among them.
Scenario
Let's say the home page should not prompt login dialog. It should let users pass through without whatever login is. However, in the same applicatiopn, in a different folder presumably, another page needs to check user permission against database table using user network login ID. By default IE treats all web site with only hostname a Intranet. By its default intranet setting, it will not prompt the login dialog and pass user login and password to the application if Windows Authentication is used. However, the tricky party is, if the application has an actual domain, IE will think it is an Internet site, and it will prompt the login and password if Windows Authentication is used.
The only way to not to promopt login dialog for Internet site using Windows Authentication, is to also turn on the anonymous authentication in IIS. However, you will lose the ability to capture the login info because the Anonymous has precedence over the Windows Authentication. The good news is there is a way to resolve that issue. If an application subfolder needs to capture the login information, you will need to overwrite the parent authorization in Location element in web.config.
1 In IIS, configure Authentication as follows:
Enable Anonymous Authentication,
Enable Windows Authentication
2 Add the followings in Web.Config.
<authentication mode="Windows" />
<authorization>
<allow users="*" />
</authorization>
<!-- secured is the relative subfolder name. deny anonymous user, so only the authenticated login will pass through -->
<location path="secured" allowOverride="true">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
Remove the application, then add this to the top-level web.config:
<configuration>
<system.web>
<!-- applies application wide -->
</system.web>
<location path="securedirectory" allowOverride="false">
<system.web>
<!-- applies only to the path specified -->
</system.web>
</location>
</configuration>
MSDN Reference

Resources