【问题标题】:Parse Azure search query filter解析 Azure 搜索查询筛选器
【发布时间】:2021-06-01 12:42:25
【问题描述】:

我的服务器充当用户搜索请求的代理。在 Azure 上请求数据之前,我们需要确保一切都是安全的。为此,我们将某些过滤器添加到查询过滤器中。 假设我的服务器收到了这个查询:

search=&$top=10&$filter=customer/customerId gt 1 and customer/customerId lt 5

我想把它拆开,一块一块地调查它的过滤器,并在里面注入一个安全过滤器。

我做的第一件事是得到过滤器:

var parsed = HttpUtility.ParseQueryString(query);
var filter = parsed["$filter"];

接下来,我想对其进行处理以进行验证和更改。 阅读this post 后,我正在尝试像这样使用ODataUriParser

// 1. Create a dummy model 
public static IEdmModel GetEdmModel()
{
    var model = new EdmModel();

    EdmEntityType customer = new EdmEntityType("Namespace", "Customer");
    customer.AddKeys(customer.AddStructuralProperty("CustomerId", EdmPrimitiveTypeKind.Int32));
    model.AddElement(customer);

    return model;
}


// 2. Utilize it
static void Foo()
{
    var query = "search=&$top=5001&$filter=Customer/CustomerId eq 1";


    var parsed = HttpUtility.ParseQueryString(query);
    var filter = parsed["$filter"];

    var result = new ODataUriParser(HardCodedTestModel.TestModel, new Uri(filter, UriKind.Relative));
    var parsedFilter = result.ParseFilter();
}

这向我抛出了一个异常,说:

未处理的异常。 Microsoft.OData.UriParser.ODataUnrecognizedPathException:资源不 为细分“客户”找到

  1. 我做错了什么?
  2. 有没有更简单的方法来实现我想要的?

【问题讨论】:

    标签: c# .net parsing odata azure-cognitive-search


    【解决方案1】:

    您的 EDM 模型似乎不包含 entity set,因此不清楚过滤器正在过滤什么。 Azure 认知搜索为每个索引定义了一个 EDM 模型,其中包括一个实体集“文档”,其类型对应于索引定义。筛选器中的属性路径 Customer/CustomerId 将被 Azure 认知搜索解释为名为 Edm.ComplexType 的顶级字段 CustomerCustomerId 子字段(使用 OData 术语,文档是实体,@987654328 @ 是 Complex 属性,CustomerIdCustomer 的属性。如果您想使用 ODataUriParserODataQueryOptionParser 从过滤器文本中获取语义 AST,您的 EDM 模型必须包含所有这些架构信息。

    也就是说,您可能不需要完整的语义 AST 来验证过滤器表达式的安全性(假设您正在尝试防御诸如注入攻击之类的事情)。单独使用 OData 过滤器解析器的 lexical stage 可能更简单。然后你可以处理语法 AST。

    如果您想要最大程度的控制,您可以随时使用自己的解析器。 OData 的完整 BNF 为 here

    【讨论】:

    • 嘿布鲁斯。谢谢你的回答,我去了Microsoft.OData.UriParser.UriQueryExpressionParser。我设法检查了初始过滤器并将我的安全过滤器注入其中。使用ISyntacticTreeVisitor 我实现了两个访问者。一种用于安全注入,另一种用于将 AST 解析回字符串 OData 查询。虽然,我觉得我的方法并不理想。并且应该有现成的工具来将QueryToken 转换回字符串。我一直在寻找整个互联网,但没有找到任何东西。请给点建议好吗?
    • 我不知道有任何现有的库可以做到这一点。我认为滚动您自己的访问者是可行的方法(Azure 认知搜索在内部为调试我们的 OData 过滤器处理器所做的工作)。
    猜你喜欢
    • 2021-09-02
    • 2019-09-26
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多