Serving mobile-specific login page with MediaProtect
Hi all,
I thought this might help someone. I've implemented the mobile version of a site using an alt template - all mobile page requests should end in /m, and my alt template, called "m", will handle laying it out for mobile. So when a mobile user requests a protected pdf that they don't have access to, they should be bounced to /login/m (rather than /login). Here's how I did it, by hooking into the Request_FileRequesting event.
One question though, I'd love to not have to hardcode the urls (i.e. /login and /login/m). How could I retrieve the RedirectPage as specified by the client when they are protecting their media items? That way I wouldn't rely on the login page always being called "login" :)
Thanks,
David
Note: You'll need to add references to both MediaProtect and MediaProtect.Library dlls in your project for this to compile.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Security; using MediaProtect.Library; using umbraco.BusinessLogic; using umbraco.NodeFactory; namespace CharlesTaylor.SharedLogic { public class MediaProtectForMobileHandler : ApplicationBase { /// /// Example code for the Requesting event /// public class ProtectedFolderRequest : ApplicationBase { /// /// Constructor to wire up the requesting event /// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit /// public ProtectedFolderRequest() { Request.FileRequesting += Request_FileRequesting; }
/// /// Handles the FileRequesting event to check if the user has access /// private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e) {
if (!MediaProtect.Access.MediaAccess.HasAccess(e.MediaId, Membership.GetUser())) { // Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower(); var homeNode = Node.GetNodeByXpath("/root/Homepage"); if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value)) { // If it's a mobile request then bounce to the mobile version of the login page if (homeNode.GetProperty("mobileUrl").Value.Contains(server)) { e.RedirectPage = "/login/m"; } else { e.RedirectPage = "/login/"; } } e.Cancel = true; } } } } }
Thanks for sharing this. The reason why there is no API support from the library is that usually you only validate something different than an Umbraco media item. Then you don't know what the media item was.
But I had the exact same issue when implementing support for ImageGen :) So I think the code below will work
ValidationResult result = ValidationHelper.Validate(e.Path);
e.Cancel = !result.HasAccess;
if (e.Cancel)
{
e.RedirectPage = result.RedirectPage;
}
You only need to append /m to the mobile login page. I will add a work item for me to support this in the library itself since you have all the Methods in one place then
Thanks Richard, that's excellent, here is my re-factored class which uses the user-defined login path:
using System;
using System.Web;
using MediaProtect.Helpers;
using MediaProtect.Library;
using umbraco.BusinessLogic;
using umbraco.NodeFactory;
namespace CharlesTaylor.SharedLogic
{
public class MediaProtectForMobileHandler : ApplicationBase
{
/// <summary>
/// Example code for the Requesting event
/// </summary>
public class ProtectedFolderRequest : ApplicationBase
{
/// <summary>
/// Constructor to wire up the requesting event
/// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit
/// </summary>
public ProtectedFolderRequest()
{
Request.FileRequesting += Request_FileRequesting;
}
/// <summary>
/// Handles the FileRequesting event to check if the user has access
/// </summary>
private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e)
{
// Check if the current user has access or not
var result = ValidationHelper.Validate(e.Path);
e.Cancel = !result.HasAccess;
if (e.Cancel)
{
// Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node
var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();
var homeNode = Node.GetNodeByXpath("/root/Homepage");
if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value))
{
// If it's a mobile request then bounce to the mobile version of the login page, as chosen by the user
e.RedirectPage = homeNode.GetProperty("mobileUrl").Value.Contains(server) ? String.Format("{0}m/", result.RedirectPage) : result.RedirectPage;
}
}
}
}
}
}
using System;
using System.Web;
using MediaProtect.Helpers;
using MediaProtect.Library;
using umbraco.BusinessLogic;
using umbraco.NodeFactory;
namespace SharedLogic
{
public class MediaProtectForMobileHandler : ApplicationBase
{
/// <summary>
/// Constructor to wire up the requesting event
/// Make sure your class derives from ApplicationBase otherwise this constructor never gets hit
/// </summary>
public MediaProtectForMobileHandler()
{
Request.FileRequesting += Request_FileRequesting;
}
/// <summary>
/// Handles the FileRequesting event to check if the user has access
/// </summary>
private void Request_FileRequesting(object sender, MediaProtect.Library.EventArgs.FileRequestingEventArgs e)
{
// Check if the current user has access or not
// http://our.umbraco.org/projects/website-utilities/media-protect/mediaprotect-general/44854-Serving-mobile-specific-login-page-with-MediaProtect
var result = ValidationHelper.Validate(e.Path);
e.Cancel = !result.HasAccess;
if (e.Cancel)
{
// Check if the request is on the mobile site or not by comparing the path with the mobile url for the site from the Homepage node
var server = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();
var homeNode = Node.GetNodeByXpath("/root/Homepage");
if (homeNode != null && homeNode.GetProperty("mobileUrl") != null && !string.IsNullOrEmpty(homeNode.GetProperty("mobileUrl").Value))
{
// If it's a mobile request then bounce to the mobile version of the login page, as chosen by the user
e.RedirectPage = homeNode.GetProperty("mobileUrl").Value.Contains(server) ? String.Format("{0}m/", result.RedirectPage) : result.RedirectPage;
}
}
}
}
}
Serving mobile-specific login page with MediaProtect
Hi all,
I thought this might help someone. I've implemented the mobile version of a site using an alt template - all mobile page requests should end in /m, and my alt template, called "m", will handle laying it out for mobile. So when a mobile user requests a protected pdf that they don't have access to, they should be bounced to /login/m (rather than /login). Here's how I did it, by hooking into the Request_FileRequesting event.
One question though, I'd love to not have to hardcode the urls (i.e. /login and /login/m). How could I retrieve the RedirectPage as specified by the client when they are protecting their media items? That way I wouldn't rely on the login page always being called "login" :)
Thanks,
David
Note: You'll need to add references to both MediaProtect and MediaProtect.Library dlls in your project for this to compile.
Hi David,
Thanks for sharing this. The reason why there is no API support from the library is that usually you only validate something different than an Umbraco media item. Then you don't know what the media item was.
But I had the exact same issue when implementing support for ImageGen :) So I think the code below will work
You only need to append /m to the mobile login page. I will add a work item for me to support this in the library itself since you have all the Methods in one place then
Thanks,
Richard
Thanks Richard, that's excellent, here is my re-factored class which uses the user-defined login path:
Cheers,
David
Two further things:
Cheers,
David
Updated code:
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.