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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ppittleCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.