2

I have an area that is a mobile layout. I then also have controllers in my route that just uses a normal website layout.

The problem is when i use [Authorize(Roles = "ROLENAME")] and the user isn't in role the page(mobile site) gets redirected to the normal website login page and not the mobile one.

Is it possible to have it switch between logins depending on the area the user is trying to access the site?

I've tried adding the following in my area web.config but it didn't work:

<authentication mode="Forms">
      <forms loginUrl="~/Activation/Login/Index" timeout="2880" />
</authentication>

Any suggestions?

tereško
  • 58,060
  • 25
  • 98
  • 150
Jeandre Pentz
  • 992
  • 2
  • 9
  • 20

1 Answers1

2

When you login Action gets hit, check if they are on a mobile device and then redirect to the mobile login page if they are.

private static string[] mobileDevices = new string[] {"iphone","ppc",
                                                      "windows ce","blackberry",
                                                      "opera mini","mobile","palm",
                                                      "portable","opera mobi" };

public static bool IsMobileDevice(string userAgent)  
{  
    // TODO: null check
    userAgent = userAgent.ToLower();  
    return mobileDevices.Any(x => userAgent.Contains(x));
}

Then in your Action:

public ActionResult Index()
{
    if (MobileHelper.IsMobileDevice(Request.UserAgent))
    {
        // Send to mobile route.
         return RedirectToAction("Login", "MobileActivation");
    }

    // Otherwise do normal login
}

Edit:

If you wanted to apply this broadly accross your application you could do the following.

Create an ActionFilter that you could apply anywhere something like this:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class RedirectToMobileArea : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var rd = filterContext.HttpContext.Request.RequestContext.RouteData;
        var currentAction = rd.GetRequiredString("action");
        var currentController = rd.GetRequiredString("controller");
        string currentArea = rd.Values["area"] as string;

        if (!currentArea.Equals("mobile", StringComparison.OrdinalIgnoreCase) && MobileHelper.IsMobileDevice(Request.UserAgent))
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", currentController }, { "action", currentAction }, { "area", "mobile" } });
        }
    }
}

This filter will take any action check if its mobile (and not in mobile area already) and send it to same action and controller in the mobile area. NOTE If you go with controllers of same name you will have to register your routes with the controller namespace see this answer

Then you could either apply the filter to each action like:

[RedirectToMobileArea]
public ActionResult Index()
{
// do stuff.
}

Or if you want to do it EVERYWHERE create a BaseController that all your controllers inherit from and apply it to that:

[RedirectToMobileArea]
public abstract class BaseController : Controller {

}

Then inherit from it:

public HomeController : BaseController {

}

I havent tested any of this but it should work...

Community
  • 1
  • 1
shenku
  • 11,969
  • 12
  • 64
  • 118