gpt4 book ai didi

c# - 每个实体的 Web API OData 安全性

转载 作者:IT王子 更新时间:2023-10-29 03:52:36 25 4
gpt4 key购买 nike

背景:
我有一个非常大的 OData 模型,目前正在使用 WCF 数据服务 (OData) 来公开它。但是,Microsoft 声明 WCF 数据服务是 dead并且 Web API OData 是他们的发展方向。

所以我正在研究让 Web API OData 和 WCF 数据服务一起工作的方法。

问题设置:
模型的某些部分不需要保护,但有些部分需要保护。例如,客户列表需要安全性来限制谁可以阅读它,但我还有其他列表,例如产品列表,任何人都可以查看。

Customers 实体有许多可以访问它的关联。如果算上 2+ 级关联,则可以通过数百种方式联系客户(通过关联)。例如 Prodcuts.First().Orders.First().Customer。由于客户是我系统的核心,您可以从几乎任何实体开始,并最终将您的方式关联到客户列表。

WCF 数据服务让我可以通过如下方法为特定实体提供安全保护:

[QueryInterceptor("Customers")]
public Expression<Func<Customer, bool>> CheckCustomerAccess()
{
return DoesCurrentUserHaveAccessToCustomers();
}

当我查看 Web API OData 时,我没有看到类似的内容。另外,我非常担心,因为我正在制作的 Controller 在遵循关联时似乎没有被调用。 (这意味着我不能在 CustomersController 中设置安全性。)

我担心我将不得不尝试以某种方式列举协会可以接触客户并为每个客户提供安全保障的所有方式。

问题:
有没有办法为 Web API OData 中的特定实体提供安全保护?(无需枚举所有可能以某种方式向下扩展到该实体的关联?)

最佳答案

UPDATE: At this point in time I would recommend that you follow the solution posted by vaccano, which is based on input from the OData team.

您需要做的是为 OData 4(或 QuerableAttribute,具体取决于您正在使用的 Web API\OData 版本)创建一个继承自 EnableQueryAttribute 的新属性,并覆盖 ValidateQuery(其方法与继承自QuerableAttribute) 检查是否存在合适的 SelectExpand 属性。

要设置一个新项目来测试它,请执行以下操作:

  1. 使用 Web API 2 创建一个新的 ASP.Net 项目
  2. 创建您的 Entity Framework 数据上下文。
  3. 添加一个新的“Web API 2 OData Controller ...” Controller 。
  4. 在 WebApiConfigRegister(...) 方法中添加以下内容:

代码:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

builder.EntitySet<Customer>("Customers");
builder.EntitySet<Order>("Orders");
builder.EntitySet<OrderDetail>("OrderDetails");

config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

//config.AddODataQueryFilter();
config.AddODataQueryFilter(new SecureAccessAttribute());

在上面,Customer、Order 和 OrderDetail 是我的 Entity Framework 实体。 config.AddODataQueryFilter(new SecureAccessAttribute()) 注册我的 SecureAccessAttribute 以供使用。

  1. SecureAccessAttribute 实现如下:

代码:

public class SecureAccessAttribute : EnableQueryAttribute
{
public override void ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)
{
if(queryOptions.SelectExpand != null
&& queryOptions.SelectExpand.RawExpand != null
&& queryOptions.SelectExpand.RawExpand.Contains("Orders"))
{
//Check here if user is allowed to view orders.
throw new InvalidOperationException();
}

base.ValidateQuery(request, queryOptions);
}
}

请注意,我允许访问 Customers Controller ,但我限制访问 Orders。我实现的唯一 Controller 是下面的 Controller :

public class CustomersController : ODataController
{
private Entities db = new Entities();

[SecureAccess(MaxExpansionDepth=2)]
public IQueryable<Customer> GetCustomers()
{
return db.Customers;
}

// GET: odata/Customers(5)
[EnableQuery]
public SingleResult<Customer> GetCustomer([FromODataUri] int key)
{
return SingleResult.Create(db.Customers.Where(customer => customer.Id == key));
}
}
  1. 在您要保护的所有操作中应用该属性。它的工作原理与 EnableQueryAttribute 完全相同。可以在此处找到完整的示例(包括 Nuget 包结束一切,下载 50Mb):http://1drv.ms/1zRmmVj

我只想对其他一些解决方案发表一些评论:

  1. Leyenda 的解决方案之所以不起作用,仅仅是因为它是相反的,但在其他方面非常接近!事实上,构建器将在 Entity Framework 中查找以扩展属性,而根本不会访问 Customers Controller !我什至没有一个,如果您删除安全属性,如果您将扩展命令添加到您的查询中,它仍然会很好地检索订单。
  2. 设置模型构建器将禁止全局访问您删除的实体以及所有人,因此这不是一个好的解决方案。
  3. Feng Zhao 的解决方案可以工作,但您必须在每个查询中手动删除要保护的项目,到处都是,这不是一个好的解决方案。

关于c# - 每个实体的 Web API OData 安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24981806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com