我正在使用 ASP.NET MVC 和使用 Repository 模式进行数据访问的实体框架来实现 Web 应用程序。此应用程序将有几个不相关的用户创建对象。每个用户应该只能访问他们自己的对象。
是否有任何模式或内置 EF 功能提供一种方法来确保用户只能访问自己的记录?
我目前正在考虑向所有私有域对象添加一个所有者字段,并实现一个对数据库的所有查询都必须通过的类。此类将确定被查询的域对象是否是私有的。如果是这样,这个类将在查询中附加一个关于所有者的过滤器。这听起来合理吗?
我正在使用 ASP.NET MVC 和使用 Repository 模式进行数据访问的实体框架来实现 Web 应用程序。此应用程序将有几个不相关的用户创建对象。每个用户应该只能访问他们自己的对象。
是否有任何模式或内置 EF 功能提供一种方法来确保用户只能访问自己的记录?
我目前正在考虑向所有私有域对象添加一个所有者字段,并实现一个对数据库的所有查询都必须通过的类。此类将确定被查询的域对象是否是私有的。如果是这样,这个类将在查询中附加一个关于所有者的过滤器。这听起来合理吗?
您问题的第二部分非常接近Repository Pattern的描述。这种方法可用于通过强制插入用户特定的过滤器来解决逐个记录的访问问题。
这种方法将您的客户端业务逻辑与基于行的安全性实现分离:如果您以后决定更改实现逐条记录访问的方式,您需要修改的只是您的存储库实现。客户端甚至不需要重新编译。
EF 将所有业务实体的存储库定义为部分类。您可以在其之上添加一个接口(在单独的文件中),并使用 EF 生成的方法实现存储库的方法:
IMyRepository {
IQueryable<ClientOrder> Orders;
IQueryable<ServiceIssue> Issues;
}
// The other part of MyRepository is EF-generated.
// Assume that EF provides properties these properties:
// - ObjectSet<ClientOrder> AllOrders
// - ObjectSet<ServiceIssue> AllIssues
public partial SecureRepository : IMyRepository {
private readonly Guid userId;
public SecureRepository(Guid userId) : this() {
this.userId = userId;
}
public IQueryable<ClientOrder> Orders {
get {
return AllOrders.Where(ord => ord.UserId == userId);
}
}
public IQueryable<ServiceIssue> Issues {
get {
return AllIssues.Where(csi => csi.UserId == userId);
}
}
}
UserId
在将订单和问题保存到数据库之前,您可以添加用于设置订单和问题的写入方法。