【问题标题】:Record-level Security in LINQ-to-SQLLINQ-to-SQL 中的记录级安全性
【发布时间】:2011-03-10 04:10:54
【问题描述】:

我正在为 LINQ-to-SQL 应用开发记录级安全系统。我目前有一个围绕 DataContext 的 GetTable 方法的包装器,该方法将 T 连接到用户交叉引用表。 T 是任何实现我的 ISecurable 接口的类:

public interface ISecurable
{
    bool CanRead { get; set; }
    bool CanUpdate { get; set; }
    bool CanDelete { get; set; }
}

我的基础存储库类执行连接并为指定用户更新每个故事的 CanRead、CanUpdate 和 CanDelete 属性:

var storiesVisibleToUser = repository.Get<Story>( user );

我想用扩展方法替换包装器,所以我可以这样做:

var storiesVisibleToUser = repository.Get<Story>().ApplySecurity( user );

这是一个微妙的变化,但会大大减少安全代码和通用数据访问代码之间的耦合,因此它可以让我更灵活地添加诸如组级安全性之类的东西。

问题是ApplySecurity扩展方法无权访问原始DataContext,所以它不能使用GetTable来检索交叉引用记录。

两个问题:

  1. 有什么方法可以得到一个 IQueryable 的 DataContext,缺少subclassing/wrapping it and passing the context in to the constructor

  2. 扩展方法是执行此操作的“正确”方法,还是我应该坚持使用我的存储库中可以访问原始上下文的方法?

【问题讨论】:

  • 我不会在这里使用扩展方法。打破对您的数据应用安全性的步骤会使您的代码打开以检索没有应用安全性的数据,这会违背目的。我会将安全性封装在您的存储库方法中,就像您拥有它一样。如果你走这条路,你不必担心你的问题 #1。
  • 代码中有一些地方需要检索记录,即使当前用户没有访问权限。例如,我们可能希望向用户显示一个故事名称列表,包括他原本没有读取权限的那些。在现有代码中,Get 方法具有一个带有布尔参数的重载,用于选择性地包含此类记录。在其他地方,管理员用户需要知道哪些用户有权访问某些记录,因此为不同的用户多次调用扩展方法可能是有益的。
  • 如果用户可以“看到”数据,那么根据定义,他们可以访问它......我错过了什么吗?
  • @Nate:用户不是代码。该代码可以在将数据以 JSON、HTML 等形式发送给用户之前对数据执行各种转换。我承认边界有点模糊。安全设置最终更像是代码应该遵循的准则,而不是硬性规定。
  • 我的最后一条评论是:理想的设置可能有自定义“角色”,而不仅仅是“CanRead”、“CanUpdate”和“CanDelete”。这将消除用户可以在某些视图中查看他们没有 CanRead 权限的数据的模糊性。

标签: c# linq-to-sql iqueryable


【解决方案1】:

一种可能的解决方案是在 Story 和交叉引用表之间创建关联。然后,另一个表可用于 Story 查询,而无需引用原始上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多