3

我喜欢 OData,而且我特别高兴它被 ASP.NET Web API 采用。

我创建了一些服务供内部应用程序使用,但从不供公众使用。主要原因是 OData 的开放性似乎很难让“安全”免受滥用。

最具体地说,我担心鉴于运行任意查询的能力,用户可能会表达一个复杂的查询,这会给操作系统带来压力,以至于对所有其他用户的体验都不好。

在 WebApi 控制器中,OData 端点公开如下:

public class OrderController
{
    [Queryable]
    public IQueryable<Orders> Get()
    {
         // Compose and return the IQueryable<Orders>
    }
}

这可以完全控制查询的组合和执行过程,但通过复杂的IQuerable<T>界面来实现。为用户提供信息的子集变得微不足道,例如附加 aWhere以仅包括他们有权访问的记录。

是否有IQueryable<T>可以包装现有IQuerable<T>实例以限制用户可以运行的查询的实现?我最感兴趣的是限制查询的复杂性,但我也希望能够防止用户遍历与他们不应该访问的资源的关联。

4

2 回答 2

3

我认为您会很高兴在 RTM 中了解到这一点,我们添加了一些选项,让您可以自定义要向用户公开的查询类型。所以你可以这样做,例如:

[Queryable(
    AllowedFunctions = AllowedFunctions.AllStringFunctions,
    AllowedLogicalOperators = AllowedLogicalOperators.Equal,
    AllowedOrderByProperties = "ID")]

并以几种常见的方式限制您的查询。如果您想进一步限制查询,可以插入验证钩子,例如ODataQueryValidator或通过覆盖属性ValidateQuery上的方法。[Queryable]

您可以使用我们的夜间构建来访问这些功能,或者自己构建最新的位。

于 2013-01-14T19:11:36.193 回答
2

而不是使用 Queryable 属性(您缺少),您不能使用此属性,而是手动接受 ODataQueryOptions 参数,这使您可以访问各种过滤器、顶部等选项以允许验证它们。

OData 查询调用的任何函数都可以传递一个参数 ODataQueryOptions,例如:

public IQueryable<T> Get(ODataQueryOptions options)`  
{ 
//Use the following vars to fetch the values, and check if
//they are as you expect them to be. etc.  
options.Top.RawValue;
options.Filter.Value;
options.Filter.ApplyTo();
}

在这种情况下,您可以跳过 [Queryable] 属性并使用ApplyTo手动将各种查询应用于结果。:)

于 2013-01-14T16:49:42.750 回答