How to prevent unauthenticated users from downloading files not managed by ASP.NET (e.g. .mp3, .gif)

I need to make some non-asp.net managed files, such as .mp3's, only available to users who have logged in (via forms authentication).

I've read that one way to do this is to map the file type to the ASP.NET engine, but I'd rather not do that.

I'm assuming that locating the download-able files in a folder above the web's root (e.g. c:\ProtectedFiles) would be a part of the puzzle.

What I'm looking for is the easiest method for implementing this.

Oh, using ASP.NET 2.0, if that makes a difference.
cdakzAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
ppittleConnect With a Mentor Commented:
cdakz,

You are correct; one solution is to modify IIS so the ASP.NET ISAPI filter handles all file types by using Wildcard Application Mapping. There are some draw backs to this approach (http://blogs.msdn.com/david.wang/archive/2005/10/15/Why-Wildcard-application-mapping-can-disable-Default-Document-resolution.aspx), although the experience should be better in IIS 7.

However, if you're not interested in that approach, an alternative is to use a wrapper file to stream the files back to a user.  Instead of a offering users a link such as http://mysite.com/files/music.mp3, you'd offer them a link such as http://mysite.com/streamFile.aspx?path=/files/music.mp3.  The streamFile.aspx file would then be responsible for validating the path parameter (this is quite important as users could enter whatever value they please for the path QueryString parameter), reading the file into memory, and sending it back to the user.  Here's the URL of a blog post that discusses this approach and contains the code for an example: http://www.kaelisspace.com/wordpress22/2008/04/03/aspnet-c-stream-a-download-file/.

Setting the UAC (User Access Control - ie file/folder permissions) of a directory, unfortunately, doesn't have the intended results you're looking for.  When ASP.NET access the NTFS file system it has to use a valid Windows account and that Windows account has to have enough permissions (ie read) to pass the UAC checks.  The Windows account is tied to the ASP.NET executable (aspnet_wp.exe in IIS 5 and w3wp.exe in IIS 6).  By default the ASP.NET executable executes under the ASP.NET Machine Account.  There are a number of ways to modify this.  It can be done programmatically via the WindowsIdentity.Imperosnate() method (http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx) or in the web.config via the Identy tag by setting the Impersonate Property to true and providing a Username and Password.

However, when IIS is serving non-ASP.NET files, none of that matters.  IIS uses its own Windows account to read the file and send it back to users and if you're using ASP.NET is Forms Authentication mode and IIS is set to anonymous access, IIS won’t provide any security.

Do keep in mind if you use the streamFile.aspx pattern I recommended above, you'll need to make sure the ASPNET Machine Account has at least read access to the directory housing the files.

One other side benefit you get from using a streamFile.aspx pattern, is you're abstracting file access.  If you ever need to change your backend file repository, for example going from a file system to a housing your files in a database, you'd only need to update streamFile.aspx as opposed to modifying every file link in your site.

HTH

PJ
0
 
Kusala WijayasenaSoftware EngineerCommented:
Create a separate folder in web root and put separate web config file to it and you can control access to that folder by configuring web config added

http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_21692750.html
http://support.microsoft.com/kb/815151 

-Kusala
0
 
cdakzAuthor Commented:

Kusala, the web.config only controls access to files managed by ASP.NET, such as .aspx, .ascx, etc. Is there something else I'm missing (entirely possible), perhaps in those URLs you provided.
Looks like I'm going to need to get familiar with http handlers, per PPittle and AmanBhullar's responses (still digesting them).
However, AmanBhullar, I do have a quick follow up question. The URL you provided links to an article that says to put the dll that results from the code into the bin folder. It sounds like it means a .dll that's specific to the code (vs. a site-wide dll, ala ASP.NET 1.1), but it doesn't explicitly say *what* to do
Can you shed more light on this? Is there a way to create a dll just for that class, outside of the rest of the web app (which is compiled just-in-time)? FYI that I'm using Visual Studio 2005.
0
All Courses

From novice to tech pro — start learning today.