How to protect some controller action(s) from being accessed by unauthorized users?
Usually you can check this.User.Identity.IsAuthenticated in each action. But that doesn't look good, does it?
What if we can have an attribute to mark actions accessible only by logged in users?
And this is possible
[RequiresAuthentication()]
public ActionResult Index()
{
...
You'll need following class to use this attribute
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Mvc;
public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//redirect if not authenticated
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
RedirectToLoginUrl(filterContext);
}
}
protected void RedirectToLoginUrl(ActionExecutingContext filterContext)
{
//use the current url as return url
string returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath;
//send them off to the login page
string redirectUrl = string.Format("?ReturnUrl={0}", HttpUtility.UrlEncode( returnUrl ) );
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}
But in common cases it's better to filter access by Role. For example, you have admins and users. And some pages can be accessed only by admins. Here is another small class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
public class RequiresRoleAttribute : RequiresAuthenticationAttribute
{
protected string _RequiredRoleName;
public RequiresRoleAttribute(string roleName)
{
_RequiredRoleName = roleName;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext); // redirect if isn't logged in
//redirect if is not in role
if (!filterContext.HttpContext.User.IsInRole(_RequiredRoleName) )
{
base.RedirectToLoginUrl(filterContext);
}
}
}
And usage example
[RequiresRole("admin")]
public ActionResult Index()
{
return View();
}
That's all.
Download source