I'm actually migrating some parts of my previous WCF services to Web API.
I had used QueryInterceptor on my Machine entity which checks whether the current user has access to the desired data and returns all the data or a filtered set that they are allowed to see.
[QueryInterceptor("Machines")]
public Expression<Func<Machine, bool>> FilterMachines()
{
return CheckMachineAccess<Machine>(m => m.MachineRole==xyz && m.userHasPermission);
}
I'm finding it difficult to implement the same in Web API. I'm using odata v4, OWIN hosted web API.
Anyone has any suggestions regarding this? Thanks in advance :)
Edit: I have followed this approach. Don't know if this is the right way to follow.
[HttpGet]
[ODataRoute("Machines")]
[EnableQuery]
public IQueryable<Machine> FilterMachines(ODataQueryOptions opts)
{
var expression = CheckMachineAccess<Machine>(m => m.MachineRole==xyz && m.userHasPermission);
var result = db.Machines.Where(expression);
return (IQueryable<Machine>)result;
}
OP you are on the right track, if that is working for you then I totally support it!
I'll address the Title of your question directly first.
In OData services, a good replacement for the many QueryInterceptor implementations is to Inherit from the EnableQuery Attribute.
But how do we solve your issue of what is effectively an implementation of Row Level Security? What you have implemented already is very similar to what I would have done. You are right, in your controller method you have enough information about the context to be able to apply a filter to your query.
I had a similar idea in my projects and have a common base class for all my controllers that has a single method that all inheriting controllers must use to get the initial filtered query for their respective entity type: The following are a cut down version of my base class methods for applying security style rules to a query
So now in your controller you would override the ApplyUserPolicy method to evaluate your security rules in the specific context of the Machine data, which would result in the following changes to your endpoint.