Improving the Secured File Download UX for Unauthenticated Users
DotNetNuke has extensive security features. One of which is enforcing role based permissions when accessing files. The general workflow is to say that "Registered Users" get to see a particular file, you then create a link to that file using DNN, and as a matter of course, the roles are enforced. This uses what's known as a file ticket to request the file, so that it is not linked to directly.
This is great if you are only providing those links to currently authenticated users. However, if you want to provide these links to unauthenticated users, you get a pretty unfriendly experience. Granted, this is an edge use-case, and an argument could be made against doing this in the first place, but every project is different, and this just might make sense for you.
There are a couple of ways to get yourself into this situation - the one I set up was the following:
- Drop a links module on the page,
- add a new link to a file
- Go to the file manager, and make that file's folder available only to registered users.
- Make sure the module is visible to all users
Currently, in DNN 4.9, you get a blank white page (even if you view source) with the following content:
You do not have permission to view this file.
We could easily make that better by localizing it with a link to the login page. This improves the user experience a little bit. But really, we can put anything we want in here. Including a full HTML page with web site branding to give the user a more pleasant experience.
The value to localize can be found in GlobalResources\SharedResources.resx under the "FilePermission.Error" key. Note that any time you make a change to this file, the app restarts. So try to be patient when making changes.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>My Temporary Page</title> </head> <body> <p>Dear user, please <a href="http://localhost/dotnetnuke_2/Home/tabid/36/ctl/Login/Default.aspx">Login</a> to view the file you have requested. Thanks, Admin.</p> </body> </html>
To take it a step further, we could add a timed redirect to the page, using a meta refresh. This will give the user the ability to see a custom informational page, as well as automatically be redirected.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>My Temporary Page</title> <meta http-equiv="REFRESH" content="10;url=http://localhost/dotnetnuke_2/Home/tabid/36/ctl/Login/Default.aspx" /> </head> <body> <p>Dear user, please <a href="http://localhost/dotnetnuke_2/Home/tabid/36/ctl/Login/Default.aspx">Login</a> to view the file you have requested. You will be redirected in 10 seconds. Thanks, Admin.</p> </body> </html>
Probably a lot better now...
There are a few things that you may want to modify above for your implementation:
- timeout (on body onload)- this is how fast your page will redirect to the login page/control. If you don't want a "landing page", set this to 0.
- virtualDirectory - if you are using a virtual directory (e.g. http://localhost/dotnetnuke_2/), you'll want to set this to "dotnetnuke_2"
- loginPage - relative link to the login page/control
When we want to provide a link for unauthenticated users to a file and enforce role security, we now have the ability to:
- provide that user with more information when they click on the link
- implement consistent branding on that informational page
- automatically redirect them to the login screen
- supply a return URL so that after they login, they are taken directly to the file.
As this is just a quick and dirty implementation, I'd love to see someone with a need for this actually make it awesome. (yes, that's right...I don't even have a project to implement this on...)
And as always, if you have a project to share with the community, you should submit it to dnnGallery!
A note about unwanted redirects
One catch with the meta refresh is that the DNN language editor shows you a preview of the content. So after you localize it with a meta refresh the first time, ever subsequent time you visit the SharedResources language file in the editor, the page will redirect.