Thursday, July 31, 2008

ASP.Net Dynamic File Download Protection

I spent a little while today playing with a way to stop users who haven't registered with a site from downloading files. With the help of two examples, I came up with the following. Hope it is useful. Just copy the code by highlighting it, as some of it might slide under the right column (I know, this is a cheesy way to post code, in the queue to do is to widen this blog template and to find a better code poster. Any suggestions for either are appreciated). Anyways, here is the code snippet.

//http://www.codeproject.com/KB/aspnet/SecureFileDownload.aspx
//http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2855600&SiteID=1
if (Request.QueryString["fid"] != null) //&& Session["uid"] != null)
{
string sPath = Server.MapPath("~") + "Your path here";
string sFileName = "";
if (Request.QueryString["fid"].ToString() == "1")
{
sPath +=
"real_file_name.config";
sFileName =
"display_file_name.pdf"; //or .doc, .jpg, .mp3, whatever
Response.AddHeader("content-disposition", "attachment; filename=" + sFileName);
Response.ContentType =
"application/octet-stream";
System.IO.
FileStream fs =
System.IO.
File.Open(sPath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
Byte[] flen = new byte[256];
int iBytes = fs.Read(flen, 0, flen.Length);
Response.Buffer =
true;
Response.BinaryWrite(flen);
while (iBytes != 0)
{
iBytes = fs.Read(flen, 0, flen.Length);
Response.BinaryWrite(flen);
}
fs.Close();
Response.End();
}


Place this in either your Page_Init or Page_Onload, adjust the paths, names, and what not and you have your file protection (in the snippet the session check is commented out, but you can see what I was getting at). For your base file path you can use Server.MapPath("~") + "/whatevedirectory/". Also if you are writting to files, it is a good idea to keep these files in your App_Data directory, as I've heard (don't know if it is true) that messing with files outside that directory may cause your app to recycle.

The above code could probably be put into an HTTPModule, you could read real file names and display names from a database, or encrypt your query string, whatever, this will give you the basics.

No comments: