1

My problem statement is same as this question i.e., use an injected service in attribute/filter. I have tried the solution given by B Z and following is my code along the lines of solution given.

//marker attribute
public class AuthorizeViewAttribute : Attribute { }

//filter
public class AuthorizeViewFilter : IAuthorizationFilter
{
    private readonly IAccessRightsService _iAccessRightService;
    public AuthorizeViewFilter(IAccessRightsService iAccessRightService)
    {
        _iAccessRightService = iAccessRightService;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        RoleFeature roleFeature = _iAccessRightService.GetRoleFeatures();

        if (roleFeature.IsView)
        {
            //redirect to controller
        }
    }      
}

Following is the ninject binding I use:

this.BindFilter<AuthorizeViewFilter>(System.Web.Mvc.FilterScope.Controller, 0)
        .WhenControllerHas<AuthorizeViewAttribute>();

I do not need any parameter in attribute, so I figured I do not need to use WithConstructorArgument as mentioned in this answer

But my filter never gets called. I put a default constructor in AuthorizeViewAttribute , debugged and found that the control jumps to default constructor in AuthorizeViewAttribute and continues with the controller method.

I cannot find any solution to this. Any suggestions?

1
  • Please show the startup code where you register the filter and/or filter provider with Web API. Commented Feb 6, 2018 at 14:22

1 Answer 1

2

Short story : You seem to be trying to use MVC filter and MVC binding on a webapi controller. That's why it does not work.

Long story : first create a webapi filter provider ( note, you will need Ninject.Extensions.Factories package to have Func<AuthorizeViewFilter> resolved by Ninject)

public class AuthorizeViewFilterProvider : System.Web.Http.Filters.IFilterProvider
{
    private readonly Func<AuthorizeViewFilter> _authorizeViewFilterFactory;

    public AuthorizeViewFilterProvider(Func<AuthorizeViewFilter> authorizeViewFilterFactory)
    {
        this._authorizeViewFilterFactory = authorizeViewFilterFactory;
    }

    public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
        if(!actionDescriptor.GetCustomAttributes<AuthorizeViewAttribute>().Any())
            return Enumerable.Empty<FilterInfo>();

        return new[]
        {
            new FilterInfo(this._authorizeViewFilterFactory(), FilterScope.Action)
        };
    }
}

then create a webapi filter

public class AuthorizeViewFilter : System.Web.Http.Filters.IAuthorizationFilter
{
    private readonly IAccessRightsService _iAccessRightService;
    public AuthorizeViewFilter(IAccessRightsService iAccessRightService)
    {
        _iAccessRightService = iAccessRightService;
    }

    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        RoleFeature roleFeature = _iAccessRightService.GetRoleFeatures();

        if (roleFeature.IsView)
        {
            return continuation();
        }
        else
          return Task.FromResult(actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Access denied"));
    }
}

then, bind the FilterProvider in your binding setup :

this.Bind<System.Web.Http.Filters.IFilterProvider>().To<AuthorizeViewFilterProvider>();
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! That worked! One follow up question: How would we pass attribute parameter to the filter?
As a follow up, I figured it out. We can use actionContext.actionDescriptor to get CustomAttribute and associated parameters.I also discovered this post which is pretty neat: blog.ploeh.dk/2014/06/13/passive-attributes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.