tags:

views:

117

answers:

2

I would like to do this:

[RequiresAuthentication(CompanyType.Client)]
public class FooController
{    
     public ActionResult OnlyClientUsersCanDoThis()

     public ActionResult OnlyClientUsersCanDoThisToo()

     [RequiresAuthentication]
     public ActionResult AnyTypeOfUserCanDoThis()

You can see why this won't work. On the third action the controller-level filter will block non-clients. I would like instead to "resolve" conflicting filters. I would like for the more specific filter (action filter) to always win. This seems natural and intuitive.

Once upon a time filterContext exposed MethodInfo for the executing action. That would have made this pretty easy. I considered doing some reflection myself using route info. That won't work because the action it might be overloaded and I cannot tell which one is the current executing one.

The alternative is to scope filters either at the controller level or the action level, but no mix, which will create a lot of extra attribute noise.

+1  A: 

We're looking into a way to expose other filters, but no promises.

Applying a filter to the controller isn't really a "scope", it's merely a short-hand for applying it to all filters. Unfortunately, that means you can't include all but one action. One simple way you could do this is to put that one method in another controller. You could even add a custom route just for that one case so the URL doesn't have to change.

Haacked
A: 

you can put authorisation logic into the OnActionExecuting(..) method of the Controller, i.e.

public override void OnActionExecuting(ActionExecutingContext filterContext) {
    base.OnActionExecuting(filterContext);
    new RequiresAuthentication()
    { /* initialization */ }.OnActionExecuting(filterContext);
}

Hope this helps,

Thomas

Thomas