I've created a custom AuthorizeAttribute to add a level of permission security to my application.
[AuthorizeUser(AccessLevel="Read")]
I can decorate certain actions in my controller or just implement it on the entire class. I have certain controllers with a large number of actions with only a few that don't need this extra check. It makes more sense for me to apply this to the entire class and exclude a few actions.
How can I exclude actions from my custom AuthorizeAttribute? It seems as though every time the action is run it default to the class attribute rather than any attribute I provide for that specific action.
Related
What are the filters in asp.net mvc, can any one explain clearly.
How to create a custom filters in asp.net mvc 4
[Authorize]
Public ActionResults Index()
{
return View()
};
In ASP.NET MVC, controllers define action methods that usually have a one-to-one relationship with possible user interactions, such as clicking a link or submitting a form. For example, when the user clicks a link, a request is routed to the designated controller, and the corresponding action method is called.
Sometimes you want to perform logic either before an action method is called or after an action method runs. To support this, ASP.NET MVC provides action filters. Action filters are custom attributes that provide a declarative means to add pre-action and post-action behavior to controller action methods.
Check Filters-and-Attributes-in-ASPNET-MVC
The filter attribute has the Order property which can be used to manage the orders. The order needs to be the order the business process to be followed. For example if HandleError attribute is given higher order than the Authorize attribute then even an unauthorized users will be getting application errors. It would be better saying "Please Login".
In ASP.NET MVC 3 I can put AuthorizeAttribute inside Global.asax's RegisterGlobalFilters, and it will apply to all controllers' actions. But how can I exclude some controller actions so these actions can be called without the user logging in?
EDIT:
Sorry, additional question, if I add authorize on the class, how can I exclude one action?
You can't do this with global filters. As their name indicates => they are global.
One way is to have all controllers that require authorization derive from a common base controller decorated with the [Authorize] attribute. Controllers that doesn't require authorization will not derive from this base controller.
Another possibility in ASP.NET MVC 3 is to write a custom IFilterProvider which based on the context will apply or not the given filters. I would recommend you reading the following blog post.
The "Admin" area in my app contains a bunch of controllers, and it's a bit repetitive to put an [Authorize] attribute on all of them. Is there a way of telling the framework that all controllers in a certain area should have certain attributes?
Edit: Inheritance is not a solution in this case. First of all the controllers already inherits from a custom class, and secondly, it should be about decorating the classes, not inheriting them.
MVC 3 has a new feature called Global Action Filters which would be perfect for what you are doing. Since you're probably not on MVC 3 yet, you can also implement Global Action Filter in earlier versions of MVC by following this example. Just customize the solution to filter check if you are in the "Admin" area for the currently executing request, then apply your Authorize attribute.
This will allow you to do this without having to apply a common base class as you requested.
You could create a base controller that all controllers in this area derive from and decorate it with the [Authorize] attribute.
There are four options,
Create a separate base controller and make admin sectionsu inherit from it
Add the Authorise Attribute to the controller class instead of each method / Actrion
Decorate each on individually
write your own logic for authorization and add that to your current base controller
I need some data to be available on all the viewpages inside the website. The data comes from an parameter supplied to all the routes, i want to get that param and get the according data for it and make it available for all the views (including the master pages).
It would be nice if it could be done in one place.
What do i need to do to get that functionality, can it even be done?
Greetz,
Richard.
The easiest (may not be the best) would be to write a base Controller class that
1) handles one of the following events to do the job:
OnActionExecuted
OnActionExecuting
OnResultExecuted
OnResultExecuting
2) Sets the data you want to have available in ViewData.
3) Use the ViewData from your views.
4) All your Controllers must inherit from your custom base Controller.
This might not be the nicest of all approaches as I usually try to avoid inheritance like the plague, but it will work. Other options.
1) Implement it in an ActionFilter and make sure add the attribute to all ActionMethods.
2) Use something like MVC Turbine to define ActionFilter's that trigger for all ActionMethods in you ASP.NET MVC Application.
If I've applied an authorisation attribute at controller level, is it possible to override this on one of the methods on that controller?
Thanks
James
That depends upon what kind of "override" you want. You cannot remove the attribute which is on the class, but you can add the attribute to the method again in order to make things more restrictive.
Update in response to comments. First, making your own AuthorizeAttribute is somewhat dangerous. AuthorizeAttribute contains code which interacts with the caching attributes in order to ensure that the cache cannot serve protected content to a non-authorized user. At a minimum, you should subtype the existing AuthorizeAttribute rather than creating something wholly new. Generally, however, it's a better idea to use the existing AuthorizeAttribute and specialize your authorization by creating a new/finding an existing ASP.NET membership provider.
I don't think it would be good design to have a filter on an action which "overrides" a filter on a controller. However, you could change the design of the filter on the controller to not require authorization on an action of a certain name. You could, for example, override the AuthorizeAttribute.AuthorizeCore method to test for an action name in the same way the existing method tests for the user name and the roles. Take very careful note of the comments in this method regarding thread safety.
I'm not sure if this is exactly the same question, but it may help...
How to make ActionFilter on action method take precedence over same ActionFilter on controller