每个用户的实体框架行级别安全性
本文关键字:安全性 框架 实体 用户 | 更新日期: 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();
}
这样,从方法名称中,可以非常清楚地了解您在做什么。存储库不负责包含您的特定逻辑。它仅用于处理您的数据访问。