Breeze 防止恶意数据更改的策略
寻找防止恶意数据更改的方法:userA操纵(编辑或删除)属于userB的数据。因为我们在客户机上创建实体,所以我们需要将它们(或至少其中一些)分配给经过身份验证的用户 例如:Breeze 防止恶意数据更改的策略,breeze,Breeze,寻找防止恶意数据更改的方法:userA操纵(编辑或删除)属于userB的数据。因为我们在客户机上创建实体,所以我们需要将它们(或至少其中一些)分配给经过身份验证的用户 例如: var newItem = ds.createNewItem(); newItem.OwnerId(22); //this is the problem that I see. newItem.Name("New Item"); newItem.Description("I just changed your it
var newItem = ds.createNewItem();
newItem.OwnerId(22); //this is the problem that I see.
newItem.Name("New Item");
newItem.Description("I just changed your item!");
... //and so on
ds.saveChanges();
if (entityInfo.Entity.GetType() == typeof(Item)
&& (entityInfo.EntityState == EntityState.Added
|| entityInfo.EntityState == EntityState.Modified)
&& ((Item)entityInfo.Entity).OwnerId != _currentUserId) {
return false
... //and so on
假设我们知道在API上调用SaveChanges
的用户的身份,我们如何针对该用户验证实体(新的或修改的)
首先想到的是将EFContextProvider
子类化,在saveEntity之前覆盖,并根据用户的身份检查实体OwnerId
属性。例如:
var newItem = ds.createNewItem();
newItem.OwnerId(22); //this is the problem that I see.
newItem.Name("New Item");
newItem.Description("I just changed your item!");
... //and so on
ds.saveChanges();
if (entityInfo.Entity.GetType() == typeof(Item)
&& (entityInfo.EntityState == EntityState.Added
|| entityInfo.EntityState == EntityState.Modified)
&& ((Item)entityInfo.Entity).OwnerId != _currentUserId) {
return false
... //and so on
如果使用这种方法,在新的EFContextProvider
类的构造函数中建立\u currentUserId
是否有意义
一个解决这个问题的想法或者更好的方法?我认为你的思路是正确的。我自己也一直在做这件事,而且走的是同一条路
假设您已经处理了身份验证,并且有一个IPrincipal
可用。您还拥有一个自定义的IIdentity
(称之为AppIdentity
),您可以在其中为经过身份验证的用户存储UserId
Web Api的baseApicController
类通过其User
属性使ambientIPrincipal
可用。我们将在您的自定义Breeze Web Api控制器中利用这一点,其开头可能如下所示:
[Authorize]
[JsonFormatter, ODataActionFilter]
public class BreezeApiController : ApiController
{
private readonly AppContextProvider _context;
public BreezeApiController() {
// pass 'User' IPrincipal to the context ctor
_context = new AppContextProvider(User);
}
...
// one of the Query action methods
[HttpGet]
public IQueryable<Foo> Foos() {
return _context.Foos
}
...
public class AppContextProvider : EFContextProvider<AppDbContext>
{
public AppContextProvider(IPrincipal user)
{
UserId = ((AppIdentity) user.Identity).UserId;
}
public int UserId { get; private set; }
...
private bool BeforeSaveEntity(EntityInfo info)
{
var entity = info.Entity;
if (info.EntityState == EntityState.Added)
{
entity.UserId = UserId;
return true;
}
return UserId == entity.UserId || throwCannotSaveEntityForThisUser();
}
...
private bool throwCannotSaveEntityForThisUser()
{
throw new SecurityException("Unauthorized user");
}
现在,您可能希望防止UserA看到UserB的实体。因此,您的自定义EFContextProvider
可以相应地进行过滤,而不是让每个Foo
都出门
public DbQuery Foos
{
get
{
// Here the 'Context' is your EF DbContext
return (DbQuery) Context.Foos
.Where(f => f.UserId == UserId);
}
}
请注意,服务器上的自定义上下文提供程序负责设置添加实体的UserId
。无论如何,我们都不会相信客户会这么做。当然,它还负责验证修改和删除的实体的用户ID
希望这有帮助记住,这只是一个草图。真正的交易将更加复杂,并被重构为助手。谢谢沃德。这非常有帮助,很高兴知道您将以类似的方式处理这个问题。顺便说一句,我开始在控制器中进行处理,这开始变得混乱,所以感谢您朝着正确的方向推动。我将在下个月根据类似这样的查询,做一个面向安全的示例和指导主题。请继续提问并提出问题。