how to protect your media files

Rating: 4.8 / 5 stars - 4 vote(s).



Recently, we got a request from a customer to protect the uploaded media file against non authorized downloading. Here's our approach on how to handle this request. Basically, we ended up creating/coding two new data types, a user control and a simple asp.net page to protect media files.

Our first data type is in fact just a normal 'Upload Field', available out-of-the-box, but instead of saving the files into the media folder using an id (for the folder name) and it's original filename, we've coded our own 'Protected Upload Field' which saves the file onto a specific location that visitors of your website cannot reach by default.

Currently, we've implemented two different 'storage' mechanism. First option is to store files in a virtual directory under the current web. By simply disabling anonymous access on that virtual directory, one will not be able to download files from that folder. A second option is to store files on disk (can be any folder as long as it's not in the web directory), which is again not accessible by your end users. Both options are configurable through a separate section in the web.config file.

 

   1:  <protectedMedia SHA1="Key1" internalDownloadSHA1="Key2" disclaimerSHA1="Key3"> 
   2:    <storage type="VirtualDirectory" path="/documents"/>
   3:  protectedMedia>

At this point, your files are securely stored on disk. Allowing only specific member groups to download those secured files is done by creating a second data type which can store permissions. 'Multiple Group Member Picker' is a new data type that stores permission settings in xml format.

Both data types will now be used to create two new media types, 'Protected Folder' and 'Protected File'.

'Protected Folder' media type is just a basic 'Folder' media type enhanced with a single property of type 'Multiple Member Group Picker' which let your specify what groups are allowed to download media files that will be 'stored' in this 'Protected Folder' folder. A 'Protected Folder' will hold any number of 'Protected File' media files which will all inherit the permissions set on the folder level.

A 'Protected File' is a 'File' media type with a the same properties Filename (umbracoFile), Extension (umbracoExtension) and Size (umbracoBytes), and some extra properties:

- A 'Disclaimer' property (True/False) which makes it possible to redirect to a disclaimer page before downloading a secured media file

- A 'Download link' property which lets umbraco users download secured media files without having to log in first.

'Filename' property (alias = 'umbracoFile') is no longer a reference to a file in the media section, but will hold a link to a download page (configurable through web.config's protectedMedia section). For example, after uploading a 'Protected File' into a 'Protected Folder', the 'Filename' property will hold a value such as

 

http://server/download.aspx?Id=1080&Hash=27CFD76C33E267D018D6C81342582B26F33F13EB

 

whereas download.aspx is a page set up in the admin backend as the download page for secured media files.

 

   1:  <nodes>
   2:    <disclaimerNode umbracoNodeId="1058"/>
   3:    <loginNode umbracoNodeId="1057" />
   4:    <noAccessNode umbracoNodeId="1060"/>
   5:    <errorNode umbracoNodeId="1061" />
   6:    <downloadNode umbracoNodeId="1063"/>
   7:  nodes>

 

Parameters are the Id of the media (as is for 'normal' media files) and a hash code which is a secured code built up of several other parameters and a unique private key (Keys are stored in the protectedMedia section of web.config - SHA1, internalDownloadSHA1 and disclaimerSHA1).

Advantages of using the umbracoFile alias for this new type of media is that there's no need to change the syntax to list files from the media section in xslt or from within user controls.

 

   1:  <xsl:value-of select="umbraco.library:GetMedia($currentPage/data [@alias='Alias'], 'false')/data [@alias='umbracoFile']"/>

 

Only one caveat left. Insert a link to a media file from a rich text editor would yield no result as the standard umbraco code does not know on how to handle links to such kind of media types. In fact, it will not allow to insert such kind of media file unless we overwrite the existing implementation. And that is what we've done as well. We've created our own implementation of loadMedia which also allows to insert links to secured media files. And to use our implementation, we just need to change a single record in the database to make sure umbraco will use the new implementation.

 

 

All set. Or wait, what about the disclaimer property. As said a bit earlier, it can be used to make sure people who're allowed to download files to first accept a disclaimer. A single umbraco page will do just fine. If such a disclaimer is found on the media file and its value set to true, then the downloader will first be redirected to this page, which in turn will hold a link back to the download page. And no, it won't loop as the hash code will be different in both situations.

 

Enough for the talk. Later on this week, I will put together a small screencast to show off how the system can be used from an umbraco powered website. Stay tuned.