【问题标题】:Restrict access to data in OData $expand operation在 OData $expand 操作中限制对数据的访问
【发布时间】:2015-03-07 16:29:32
【问题描述】:

我的数据库中有两个实体暴露在 ASP.NET WebApi 2 OData 中:服务Employee 和Activity。为简单起见,我们假设它们如下所示:

public class Employee {
    public int Id { get; set; }
    public string Type { get; set; }
}

public class Activity {
    public int Id { get; set; }
    public int EmployeeId { get; set; }

    public virtual Employee OpenedBy { get; set; }
}

请注意,OpenedBy 属性对应于导航属性,例如我可以运行以下 OData 查询:

GET http://localhost/odata/Activities?$expand=OpenedBy

我想阻止某些员工类型在 OData 中显示。假设我无法在数据源上执行此操作,因此我必须在代码中执行此操作。

到目前为止我所做的是在EmployeesController中阻止这些类型(从EntitySetController继承):

[Queryable]
public override IQueryable<Employee> Get() {
    return dbContext.Employees.Where(e => e.Type != "Restricted").AsQueryable();
}

[Queryable]
protected override Employee GetEntityByKey([FromODataUri] int key) {
    var employee = dbContext.Employees.Find(key);
    if (employee == null || employee.Type == "Restricted") {
        throw new ODataException("Forbidden");
    }

    return employee;
}

这很好用。但是,我注意到如果我运行查询:

GET http://localhost/odata/Activities?$expand=OpenedBy

我没有点击员工控制器中的代码,因此受限制的员工记录是可见的。有什么好的方法可以防止这种情况发生?

【问题讨论】:

    标签: c# asp.net asp.net-web-api odata


    【解决方案1】:

    在这种情况下:http://localhost/odata/Activities?$expand=OpenedBy

    我认为你应该更改ActivitiesController中的代码,$expand会在那里点击Get Activity方法。

    如果你不想一直扩展 OpenedBy,你可以添加一个属性: [不可扩展]

    希望这可以帮助:)

    【讨论】:

      【解决方案2】:

      由于您说“我注意到如果我运行查询”,我的印象是这是您乐于在所有情况下限制的副作用。如果是这种情况,this article by Mike Wasson 可能对您有用。

      在那篇文章中,他提出了两种方法来限制对属性的 odata 访问:

      1. 模型的属性
      2. 以编程方式从您的 EDM 中删除它

      我没有尝试第一个,我不确定您需要使用哪个命名空间或库,但是在问题的情况下,它看起来像这样:

      public class Activity {
          public int Id { get; set; }
          public int EmployeeId { get; set; }
      
          [IgnoreDataMember]
          public virtual Employee OpenedBy { get; set; }
      }
      

      我使用了第二种方法,对于问题中给出的示例,这看起来像这样:

      var activities = modelBuilder.EntitySet<Activity>("Activities");
      activities.EntityType.Ignore(a => a.OpenedBy);
      

      我以这种方式限制了一些导航集合,并且效果很好。

      【讨论】:

        猜你喜欢
        • 2016-06-18
        • 1970-01-01
        • 1970-01-01
        • 2014-09-07
        • 1970-01-01
        • 1970-01-01
        • 2014-02-16
        • 2014-01-25
        • 1970-01-01
        相关资源
        最近更新 更多