Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebApi OData per user security on property

I have some entities which have data that must only be accessible for some users.

public class Foo
{
    public virtual Bar { get; set; }
    ...
}

public class Bar
{
    public string Secret { get; set; }
    ...
}

For example Bar.Secret must only be accessible by UserA but not by UserB. I could so something like this:

public class BarsController : ODataController
{
    [EnableQuery]
    public IHttpActionResult Get()
    {
        if (User.Identity.Name != "UserA") 
            return Unauthorized();

        return _db.Bars();
    }
}

Besides that being a bad implementation. It doesn't cover this controller:

public class FoosController : ODataController
{
    [EnableQuery]
    public IHttpActionResult Get()
    {
        return _db.Foos();
    }
}

Which could be called with /odata/Foos?$expand=Bars and then I could view Bar.Secret. I can't just disable $expand on Foo because that query is totally legit for UserA and also needed.

Is there a way to make OData validate the queries against some predicate that involves the requested entities.

Something like

public class SecureEnableQueryAttribute : EnableQueryAttribute
{
    public bool ValidateResult(IEnumerable<T> entities)
    {
        return entities.All(x => x.Secret == UserA.Secret);
    }
}
like image 404
Snæbjørn Avatar asked Oct 01 '15 14:10

Snæbjørn


People also ask

Is OData secure?

The fact is that using OData is orthogonal to authentication and authorization. That is to say, you may secure an OData API in any way you can secure a generic RESTful API.

What is $select in OData?

The $select option specifies a subset of properties to include in the response body. For example, to get only the name and price of each product, use the following query: Console Copy. GET http://localhost/odata/Products?$select=Price,Name.

Does OData require Entity Framework?

For this tutorial, we'll use Entity Framework (EF) Code First to create the back-end database. Web API OData does not require EF. Use any data-access layer that can translate database entities into models.

What is Odataqueryoptions?

OData defines parameters that can be used to modify an OData query. The client sends these parameters in the query string of the request URI. For example, to sort the results, a client uses the $orderby parameter: http://localhost/Products?$orderby=Name. The OData specification calls these parameters query options.


1 Answers

You can validate the query options before the query is executed and fail if the user is not authorized to retrieve the requested data. To do this, derive from EnableQueryAttribute and override ValidateQuery.

public class SecureEnableQueryAttribute : EnableQueryAttribute
{
    public virtual void ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)
    {
        base.ValidateQuery(request, queryOptions);

        // Insert custom logic, possibly looking at queryOptions.SelectExpand
        // or queryOptions.RawValues.
    }
}
like image 161
lencharest Avatar answered Oct 09 '22 18:10

lencharest