Reputation: 592
Situation: I´m securing my actions using the AuthorizeAttribute of MVC. I´m having several UI-components containing functionalities like INSERT, DELETE, ... which are resulting in an action if the end-user of the appliation clicks e.g. a button. Only those buttons should be visible to the user which he is allowed to execute. To avoid placing the permission for user-actions at least two times (button and controller-action) I`m thinking about that the button could determine the AuthorizeAttribute of controller and/or action to control its visibility. General: The application has multiple areas and controllers.
I found this answer (Accessing the list of Controllers/Actions in an ASP.NET MVC application) which indicates that the class ReflectedControllerDescriptor could help.
Is there a way to determine from the url the area and controller and action regarding to the existing routes within the mvc-application?
An example:
I have got a view: /shop/products/all
This view contains two links - /shop/user/recommend - /system/users/loggedon
The actions "recommend" and "loggedon" are decoreated with the Authorize-attribute and these links should be only visible if the user is allowed to execute them. Therefore if possible I want to use the already attached attribute.
Upvotes: 2
Views: 1423
Reputation: 3158
This is how I did it.
I have updated the answer. it is for mvc3.
public class MyActionAttribute : ActionFilterAttribute
{
private readonly string _conroller;
private readonly string _action;
private readonly string _id;
public class MyActionAttribute : ActionFilterAttribute
{
public bool IsAllowed(string _conroller, string _action, string _id)
{
//write your logic to check if a user is allowed to perform the given action on this controller,action and id
return UserisAllowed(_conroller, _action, _id);
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var area =filterContext.RouteData.DataTokens["area"];
if (!IsAllowed(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, filterContext.RouteData.DataTokens["id"].ToString()))
{
//send user to somewhere saying you are not allow
return;
}
base.OnActionExecuting(filterContext);
}
}
Now Apply this attribute to the controller action.
[MyAction]
public ActionResult Someview()
{
return View();
}
For the link you can check this way
if (new MyActionAttribute().IsAllowed("yourcontroller","youraction","id"))
{
Html.ActionLink(whatever)
}
I hope this gives you start. This way your logic remains at one place and can be used for edit/delete type links and also for the controller.
Upvotes: 1