在 Entity framework6 Repository 模式中限制用户仅访问 his/her 个实体
Restricting a user to access only his/her entities In Entity framework6 Repository pattern
我第一次使用 存储库模式 进行 ASP.NET MVC5 项目。它有很多角色,每个角色都有一定数量的用户。到目前为止,我已经创建了各种模型实体并且添加、更新、删除场景都运行良好。在测试过程中,我发现用户能够更新那些不属于 him/her.
的实体
我想限制用户只能访问、编辑、更新、删除那些属于用户本身的实体(数据库中的行),而不是其他实体。
我知道,我需要在某处检查当前登录用户的 userId
,但是在 Repository pattern with Entity Framework
.
的情况下我应该把这个 where 条件放在哪里
我想到的两种方法是:将模型更改为在每个实体中具有 userId
属性 或将每个实体与其父实体连接起来以获取相关的用户详细信息(完整的链获得 userId
).
的实体
实现这个的首选方法是什么?
谢谢!
将每个实体与其父实体连接起来以获取相关的用户详细信息(获取 userId 的完整实体链)会很好。创建一个具有共同 属性 Like UserId -
的 BaseEntity
public class BaseEntity {
public int UserId {get;set;}
}
其他实体将继承基础实体,这样它们就可以固有地拥有共同的 UserId 属性 -
public class OtherEntity : BaseEntity {
// properties
}
另一种解决方案是使用新的 SQL Server 2016 功能:行级安全性。
(也可在 Azure 上使用)
有了这个,您可以在数据库级别过滤查询结果。
您可以覆盖 DbContext
的 SaveChanges
方法并检查用户是否仅更改 his/her 自己的实体。此解决方案适用于使用 EntityFramework.
的任何模式
首先你需要编写一个具有 UserId
的接口,每个实体都必须实现它。
public interface IEntity
{
int UserId { get; set; }
}
public Blog : IEntity
{
public int BlogId { get; set; }
public string Url { get; set; }
public int UserId { get; set; }
}
然后你需要覆盖SaveChanges
。在此方法中,如果正在修改或删除实体,我们会检查 UserId 是否匹配,否则会抛出异常。
对于正在添加的实体,您可以分配当前的 UserId
public class ApplicationDbContext : DbContext
{
public override int SaveChanges()
{
var ModifiedDeletedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Deleted ||
E.State == EntityState.Modified).ToList();
foreach (IEntity entity in ModifiedDeletedEntities)
{
if (entity.UserId != GetCurrentUserId())
{
throw new Exception("Access Denied!");
}
}
var AddedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Added).ToList();
foreach (IEntity entity in AddedEntities)
{
entity.UserId = GetCurrentUserId();
}
return base.SaveChanges();
}
我第一次使用 存储库模式 进行 ASP.NET MVC5 项目。它有很多角色,每个角色都有一定数量的用户。到目前为止,我已经创建了各种模型实体并且添加、更新、删除场景都运行良好。在测试过程中,我发现用户能够更新那些不属于 him/her.
的实体我想限制用户只能访问、编辑、更新、删除那些属于用户本身的实体(数据库中的行),而不是其他实体。
我知道,我需要在某处检查当前登录用户的 userId
,但是在 Repository pattern with Entity Framework
.
我想到的两种方法是:将模型更改为在每个实体中具有 userId
属性 或将每个实体与其父实体连接起来以获取相关的用户详细信息(完整的链获得 userId
).
实现这个的首选方法是什么? 谢谢!
将每个实体与其父实体连接起来以获取相关的用户详细信息(获取 userId 的完整实体链)会很好。创建一个具有共同 属性 Like UserId -
的 BaseEntitypublic class BaseEntity {
public int UserId {get;set;}
}
其他实体将继承基础实体,这样它们就可以固有地拥有共同的 UserId 属性 -
public class OtherEntity : BaseEntity {
// properties
}
另一种解决方案是使用新的 SQL Server 2016 功能:行级安全性。 (也可在 Azure 上使用)
有了这个,您可以在数据库级别过滤查询结果。
您可以覆盖 DbContext
的 SaveChanges
方法并检查用户是否仅更改 his/her 自己的实体。此解决方案适用于使用 EntityFramework.
首先你需要编写一个具有 UserId
的接口,每个实体都必须实现它。
public interface IEntity
{
int UserId { get; set; }
}
public Blog : IEntity
{
public int BlogId { get; set; }
public string Url { get; set; }
public int UserId { get; set; }
}
然后你需要覆盖SaveChanges
。在此方法中,如果正在修改或删除实体,我们会检查 UserId 是否匹配,否则会抛出异常。
对于正在添加的实体,您可以分配当前的 UserId
public class ApplicationDbContext : DbContext
{
public override int SaveChanges()
{
var ModifiedDeletedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Deleted ||
E.State == EntityState.Modified).ToList();
foreach (IEntity entity in ModifiedDeletedEntities)
{
if (entity.UserId != GetCurrentUserId())
{
throw new Exception("Access Denied!");
}
}
var AddedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Added).ToList();
foreach (IEntity entity in AddedEntities)
{
entity.UserId = GetCurrentUserId();
}
return base.SaveChanges();
}