开发者

If all my .Net Controllers/Action need Authorize Attr, Why don't have a attribute to use only those who do not need?

开发者 https://www.devze.com 2023-04-06 10:57 出处:网络
I have a App that need authorization to access all Controllers/Actions. Except the Login and Error Controllers/Actions.

I have a App that need authorization to access all Controllers/Actions. Except the Login and Error Controllers/Actions.

With this scenario, working in a defensive manner is better to keep default restrict access to all Controllers/Actions(without Authorize Attribute) and select with a custom Attribute only those who do not.

Have you guys done something like this?

I have a MVC Filter that execute before all Actions if the Logged User have access to them:

public class ValidatePermissionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        bool isAuthorized = false;

        //Logic that verify if logged user have permission to access the requested Controller/Action
        ...

        //Redirect to a page Error if Logged User don't have Authorization
        if (!isAuthorized)
        {
    开发者_如何转开发        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
            redirectTargetDictionary.Add("action", "Erro");
            redirectTargetDictionary.Add("controller", "Index");

            context.Result = new RedirectToRouteResult(redirectTargetDictionary);
        }
    }
}

I'm thinking the best way to do this. I can create a Blank Custom Attribute and put in the Controllers do not need authorization and check it in my Filter:

public class ValidatePermissionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        bool isAuthorized = false;

        var DoNotRequiresAuthorizationAttributes = context.ActionDescriptor.GetCustomAttributes(typeof(DoNotRequiresAuthorizationAttribute), false);

        if (DoNotRequiresAuthorizationAttributes.Length > 0)
            isAuthorized = true;

        ...

        //Redirect to a page Error if Logged User don't have Authorization
        if (!isAuthorized)
        {
            RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
            redirectTargetDictionary.Add("action", "Erro");
            redirectTargetDictionary.Add("controller", "Index");

            context.Result = new RedirectToRouteResult(redirectTargetDictionary);
        }
    }
}

What you expert Guys think?

Update:

Thinking better, I can replace my Filter with a Custom Authorize Attribute and register that to act in all Controllers/Actions in Global.asax:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new MyCustomAuthorizeAttribute());
}

Update 2:

Instead create a Blank Custom Attribute and put in the Controllers do not need authorization I pass in Parameters of my Custom Authorize the Controllers do not need authorization (in Global.asax):

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new ValidatePermissionAttribute("Login", "Erro"));
}

My Authorize Attribute:

public class ValidatePermissionAttribute : AuthorizeAttribute
{
    ...

    public ValidatePermissionAttribute(params string[] optionalControllers)
    {
        _optionalControllers = optionalControllers;
    }

    ...
}

Update 3:

Conditional Filters is the way to go.


Have you considered using Conditional Filters in ASP.NET MVC 3?


Several ways to handle bulk implementations of attributes:

  • Create a custom controller base class and implement there.
  • I think you can use the MVC filter's global filters collection: http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

I've been told before the issue with using a filter attribute is that the result can be cached via output caching, and then this wouldn't run. It's better to implement an IAuthorizationFilter interface (or AuthorizeAttribute class) and create an authorization filter instead.


If the goal is just to reduce the need to re-declare the attribute in many places, it seems one could achieve the same by creating one abstract AuthorizeController with the attribute, and any controller whose actions all require authorization can inherit that.

0

精彩评论

暂无评论...
验证码 换一张
取 消