How to create a custom attribute that will redirect to Login if it returns false, similar to the Authorize attribute - ASP.NET MVC

22,748

Solution 1

You can create a custom AuthorizeAttribute and override AuthorizeCore() and HandleUnauthorizedRequest() as required. Add your own logic which will do the check and redirect if necessary.

I'm just showing a simple example using MVC's ActionFilterAttribute (which is not the best place to do authentication/authorization)

public class VerifyUserAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var user = filterContext.HttpContext.Session["UserID"];
        if (user == null)
            filterContext.Result = new RedirectResult(string.Format("/User/Login?targetUrl={0}",filterContext.HttpContext.Request.Url.AbsolutePath));
    }
}

Do not forget to set the Session["UserID"] variable in your /User/Login action method after proper user validation.

Solution 2

You can create your own version of the Authorize attribute by implementing the IAuthorizationFilter interface. Here's an example:

class MyCustomFilter : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Session["UserID"] == null)
        {
            filterContext.Result = new RedirectResult("/");
        }
    }
}

and a usage example:

[MyCustomFilter]
public ActionResult About()
{
    ViewBag.Message = "Your application description page.";

    return View();
}
Share:
22,748
user1189352
Author by

user1189352

Updated on October 04, 2020

Comments

  • user1189352
    user1189352 about 3 years

    I tried Googling a few things about custom attributes but I'm still not sure how to go about it....

    I'm storing a few important details of the user in Session cookies (ex UserID) once the user log's in.. and all I want to do is create an attribute where if the

    if (Session["UserID"] == null)

    then it will redirect to login just like the [Authorize] attribute does. That way I can apply this attribute on the Controller level everywhere.

    Should I overwrite the Authorize attribute? Create a new one? How do I get it to redirect to login as well?

    I'm also using ASP.NET MVC 4

    Thanks for any help

  • user1189352
    user1189352 about 8 years
    Hey Thank you for this. So pretty much all I need to look into is instead of taking in the ActionFilterAttribute, look into how do to do it for the AuthorizeAttribute and I should be good? if that's correct, i got a good idea of what i need to do. Thanks!
  • Arghya C
    Arghya C about 8 years
    @user1189352 If you do not use Authorization headers and any other kind of standard validations, even this will work fine (just run and check once, I didn't). But I'd suggest to follow the standard practices of using AuthorizeAttribute, if you can.
  • user1189352
    user1189352 about 8 years
    I do use the Authorization headers. I put [Authorize] for all my controllers (if that's what you mean). Since that's the case, would it be better for me to look into overloading the Authorize attribute instead?
  • Arghya C
    Arghya C about 8 years
    I was talking about Authorization http headers. But, f you are already using [Authorize] attribute on your controllers, then you are using some authorization already. Since you are new to MVC, you can [1] First use this code as is [2] Study about MVC authorize filters, and later move to AuthorizeAttribute when you know how to use it.
  • user1189352
    user1189352 about 8 years
    thank you for the tips. i really appreciate that. i'm more into learning than just trying to copy some code.. ty!
  • Arghya C
    Arghya C about 8 years
    WC. For now, you can copy this code and work :) You can use code from the other answer (using IAuthorizationFilter) as well. Before using understand the code, so that you can fix it in case there are any issues.
  • Reuel Ribeiro
    Reuel Ribeiro over 6 years
    Just be aware that dependency injection will not be possible through constructor doing like that. If you need DI, see this answer: stackoverflow.com/questions/16708942/…
  • IceeFrog
    IceeFrog over 3 years
    This looks promising I'll try it when I get home thanks!