Breeze 确定在BeforeEntitySave中修改了哪些实体属性

Breeze 确定在BeforeEntitySave中修改了哪些实体属性,breeze,Breeze,使用自定义EFContextProvider,我想在实体保存之前检查它的哪些属性已被修改,以便实现: 安全性:客户端仅具有更改实体的某些属性的权限 审核:无论何时更改某些属性,都需要记录更改 对于使用OriginalValuesMap来确定修改后的属性,有一些建议,请参见和。如果原始值与新值不同,则属性已被修改。但是,这些原始值是由客户提供的,因此可以通过伪造来匹配新值,从而绕过此检查 我链接的第一个SO问题表明这不是问题,因为如果以这种方式伪造原始值,这些属性无论如何都不会被保存: 对于我

使用自定义EFContextProvider,我想在实体保存之前检查它的哪些属性已被修改,以便实现:

  • 安全性:客户端仅具有更改实体的某些属性的权限
  • 审核:无论何时更改某些属性,都需要记录更改
对于使用OriginalValuesMap来确定修改后的属性,有一些建议,请参见和。如果原始值与新值不同,则属性已被修改。但是,这些原始值是由客户提供的,因此可以通过伪造来匹配新值,从而绕过此检查

我链接的第一个SO问题表明这不是问题,因为如果以这种方式伪造原始值,这些属性无论如何都不会被保存:

对于我们不以任何方式使用的任何其他“未更改”属性,我们不需要担心它是否被篡改,因为即使被篡改,被篡改的值也不会持久化到数据库中

但是,这是不真实的,只要实体上的所有修改属性都伪造了其原始值。例如,以下代码将绕过基于OriginalValuesMap的服务器端安全检查,并仍保存到数据库:

manager.fetchEntityByKey('Employee', 42).then(function (result) {
    var employee = result.entity;
    employee.Salary(1000000); // do you think HR will notice?
    delete employee.entityAspect.originalValues.Salary;
    return manager.saveChanges();
});
当Breeze.NET接收到实体时,它将实体添加到处于修改状态的实体框架上下文中,并且没有标记为修改的属性,实体框架的行为是将所有提供的属性值保存到数据库中

    public override int SaveChanges()
    {
        foreach (
            var entry in
                this.ChangeTracker.Entries()
                    .Where((e => (e.State == (EntityState) Breeze.WebApi.EntityState.Modified))))
        {
            if (entry.Entity.GetType() == typeof(RestrictedClass))
            {
                var entity = entry.Entity as RestrictedClass;
                var originalEntities = RestrictedClasses.Where(e => e.Id = entity.Id).toList();
                if (originalEntities.Count == 0) continue; // user is trying to add, illegal since it says it's modified, you do different check for EntityState.Added
                var originalEntity = originalEntities[0]; // there should be only one, unique ID
                //.... now you check differences between entity and originalEntity and decide whether it's legal or not based on user role.

在我看来,这是EFContextProvider.HandleModified中的一个安全缺陷,它会覆盖要修改的EF实体状态(该方法中甚至有一条注释警告不要这样做)。在任何情况下,确定哪些属性已更改且即将保存的正确方法是什么?

在您的上下文中截取保存并检查其是否合法保存。为了便于解释,假设您想保存RestrictedClass类型的实体,并定义了表RestrictedClass,它模仿数据库中的表

    public override int SaveChanges()
    {
        foreach (
            var entry in
                this.ChangeTracker.Entries()
                    .Where((e => (e.State == (EntityState) Breeze.WebApi.EntityState.Modified))))
        {
            if (entry.Entity.GetType() == typeof(RestrictedClass))
            {
                var entity = entry.Entity as RestrictedClass;
                var originalEntities = RestrictedClasses.Where(e => e.Id = entity.Id).toList();
                if (originalEntities.Count == 0) continue; // user is trying to add, illegal since it says it's modified, you do different check for EntityState.Added
                var originalEntity = originalEntities[0]; // there should be only one, unique ID
                //.... now you check differences between entity and originalEntity and decide whether it's legal or not based on user role.