每个用户的实体框架行级别安全性

本文关键字:安全性 框架 实体 用户 | 更新日期: 2023-09-27 18:35:30

我正在开发 ASP.Net MVC3 网站,将实体框架和 SQL Server 2008 作为数据存储。此外,我还使用存储库模式将所有数据访问代码集中在一个区域中。

在我的应用程序中,我有很多用户,每个用户都可以有很多项目。用户应只能访问自己的项目。目前我有这个代码:

    public IQueryable<Project> All
    {
        get { 
            return context.Projects
                .Where(p => p.Owner.ID == Util.GetCurrentUserID())
                .Select(p=>p); 
        }
    }
    public Project Find(System.Guid id)
    {
        return context.Projects
                .Where(p => p.Owner.ID == Util.GetCurrentUserID())
                .FirstOrDefault();
    }

如果您注意到.Where(p => p.Owner.ID == Util.GetCurrentUserID())是重复的。我还有很多其他地方散落着这些确切的条件。

在 DbContext 中是否有办法始终将此条件自动附加到任何查询的"项目"表中?

像这样:

public class MyContext : DbContext
{
    public DbSet<Project> Projects
         .Where(p => p.Owner.ID == Util.GetCurrentUserID()) { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Project> Projects { get {
           // Insert a cast from IQuerieable to DBSet below
       return Projects
              .Where(p => p.Owner.ID == Util.GetCurrentUserID())
              .Select(p => p);
    } 
    set; }
}

UPD在写问题时,意识到最后一个版本可以正常工作-需要尝试。仍然希望听到代码优化的其他选项并使其更加干燥。

提前感谢!!

每个用户的实体框架行级别安全性

你总是可以编写一个名为"WhereProject"的扩展方法。然后在将条件附加到谓词后,在扩展方法中调用标准"Where"方法。

public static IEnumerable<TSource> WhereProject<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) where TSource: Project
{
     return source.Where(p=> p.Owner.ID == Util.GetCurrentUserID() && predicate);
}
如果需要,

可以跳过谓词,或者在默认值的参数列表中将其设置为 null,如果不想使用谓词,则相应地操作。


这可能是你想要的,很简单:

public static IEnumerable<TSource> WhereProject<TSource>(this IEnumerable<TSource> source) where TSource: Project
{
     return source.Where(p=> p.Owner.ID == Util.GetCurrentUserID());
}

编辑这些解决方案对我来说听起来不对。我认为您会希望将行数据保护得更高一层,就我而言,它将是服务层。考虑服务类中的方法,如下所示:

public List<Project> GetUserProjects(User user)
{
    return repo.All().Where(p => p.Owner.ID == Util.GetCurrentUserID()).ToList();
}

这样,从方法名称中,可以非常清楚地了解您在做什么。存储库不负责包含您的特定逻辑。它仅用于处理您的数据访问。