在 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 上使用)

有了这个,您可以在数据库级别过滤查询结果。

一个很好的起点:https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-entity-framework-row-level-security/

您可以覆盖 DbContextSaveChanges 方法并检查用户是否仅更改 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();

    }