WebApi OData для каждого пользователя безопасности на имущество

У меня есть некоторые объекты, которые имеют данные, которые должны быть доступны только для некоторых пользователей.

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

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

Например Bar.Secret должен быть доступен только UserA но не UserB, Я мог бы так что-то вроде этого:

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

        return _db.Bars();
    }
}

Кроме того, это плохая реализация. Это не распространяется на этот контроллер:

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

Который может быть вызван с /odata/Foos?$expand=Bars и тогда я мог посмотреть Bar.Secret, Я не могу просто отключить $expand на Foo потому что этот запрос является абсолютно законным для UserA и тоже нужно.

Есть ли способ заставить OData проверять запросы относительно некоторого предиката, который включает запрошенные объекты.

Что-то вроде

public class SecureEnableQueryAttribute : EnableQueryAttribute
{
    public bool ValidateResult(IEnumerable<T> entities)
    {
        return entities.All(x => x.Secret == UserA.Secret);
    }
}

1 ответ

Вы можете проверить параметры запроса перед его выполнением и потерпеть неудачу, если пользователь не авторизован для получения запрошенных данных. Чтобы сделать это, производные от EnableQueryAttribute и переопределить 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.
    }
}
Другие вопросы по тегам