Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC override AllowAnonymous attribute

Is there a way to override AllowAnonymous attribute? I have implemented custom authorization that loads user menus & buttons from database as below:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new MyCustomAuthorization()); // Custom Authorization for Rights & Priveleges
}

The above works fine.

Now I want to allow access to some action if a user is authenticated, no need to check authorization in this case. Example:

[Authorize]
public class MenusAndButtonsController : BaseController
{
    [Authenticated] // my custom attribute that will check if user is logged in or not
    public JsonResult GetGeneralMenuAndButtons()
    {
        using (MealPlannerAuthorizationEntities repository = new MealPlannerAuthorizationEntities())
        {
            var MenusAndButtons = repository.MP_AUTH_Menus.Where(x => x.IsButton == false && x.IsListButton == false).Select(c => new { DisplayText = c.MenuName, Value = c.MenuId }).OrderBy(x => x.DisplayText).ToList();
            return Json(new { Result = "OK", Options = MenusAndButtons }, JsonRequestBehavior.AllowGet);
        }
    }
}

Instead of AllowAnonymous, I am trying to create my own custom attribute [Authenticated] that will check if the user is logged in or not. If user is logged in it will return true and the GetGeneralMenuAndButtons will continue its operation.

like image 677
suomi-dev Avatar asked Aug 11 '15 19:08

suomi-dev


People also ask

What is allowanonymous attribute in MVC 4?

One of the new features in ASP.NET MVC 4 is the AllowAnonymous Attribute that helps you secure an entire ASP.NET MVC 4 Website or Controller while providing a convenient means of allowing anonymous users access to certain controller actions, like the login and register Actions.

How to secure MVC controller action in MVC?

You need to specify System.Web.Mvc with the Authorize Attribute because you will find an AuthorizeAttribute in System.Web.Http, too. This now secures every controller action in the entire ASP.NET MVC 4 Website except for those that use the AllowAnonymous Attribute.

Does [allowanonymous] attribute ignore authorization and authentication flow?

Adding [AllowAnonymous] attribute or filter either to MVC Controller or as metadata to an Endpoint only ignores Authorization flow. It must also ignore Authentication flow to avoid unnecessary calls to Authentication Handlers and Policy Evaluators.

What is onauthorization method in MVC?

Here is a snippet of the OnAuthorization Method: Essentially skip authorization if you find an AllowAnonymous Attribute on the action or controller. Always fun to learn about the new features in ASP.NET MVC 4.


1 Answers

Actually AllowAnonymous class is simple empty sealed attribute class.

So when we decorate an action method with AllowAnonymous attribute, the onAuthorization method of AuthorizeAttribute simply ignores authorization and authentication checking. So in my case I also had to create an attribute (a blank sealed class inheriting from attribute class) and modify the OnAuthorization method little bit.

Below is the complete implementation:

public sealed class AuthenticateAttribute : Attribute
{
    public AuthenticateAttribute() { }
}

Then override the onAuthorization method of Authorize attribute (of course I am assuming you already have custom authorization filter implemented).

public override void OnAuthorization(AuthorizationContext filterContext)
{
    bool IsAuthenticAttribute =
        (filterContext.ActionDescriptor.IsDefined(typeof(AuthenticateAttribute), true) ||
        filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthenticateAttribute), true)) &&
        filterContext.HttpContext.User.Identity.IsAuthenticated;

    if (!IsAuthenticAttribute)
    {
        base.OnAuthorization(filterContext);
    }
}

Finally decorate your action method with our new Authenticate attribute:

[Authenticate]
public JsonResult GetParentMenus()
{
    using (MealPlannerAuthorizationEntities repository = new MealPlannerAuthorizationEntities())
    {
        var parentMenus = repository.MP_AUTH_Menus.Where(x => x.IsButton == false && x.IsListButton == false).Select(c => new { DisplayText = c.MenuName, Value = c.MenuId }).OrderBy(x => x.DisplayText).ToList();
        return Json(new { Result = "OK", Options = parentMenus }, JsonRequestBehavior.AllowGet);
    }
}
like image 158
suomi-dev Avatar answered Oct 08 '22 05:10

suomi-dev