实体框架插入需要选择权限

时间:2009-11-10 08:54:47

标签: .net security entity-framework linq-to-entities least-privilege

我们使用LINQ to Entities将条目写入Audit数据库(SQL Server 2008)。由于这是一个专用的审计数据库,我们插入行 - 我们从不读取任何行,从审计应用程序更新或删除它们。

审核应用程序应使用最小权限原则,因此我们不希望授予它超出其需要的权限。由于我们从未读过任何行,因此我们不希望授予从数据库中选择的权限。

但是,当我们尝试编写数据时,会收到以下错误消息:

  

对象'AuditEvent',数据库'IdentifyAudit',架构'dbo'拒绝了SELECT权限。

代码非常标准的EF代码:

var auditEvent = new AuditEvent();
auditEvent.EventType = eventType;
auditEvent.Timestamp = timestamp;
auditEvent.UserName = userName;
auditEvent.ApplicationId = this.ApplicationId;

this.objectContext.AddToAuditEvents(auditEvent);
this.objectContext.SaveChanges();

为什么我们需要SELECT权限才能写入表格,更重要的是:我们有什么方法可以删除该要求吗?


修改

SQL事件探查器显示正在执行的语句:

exec sp_executesql N'insert [dbo].[AuditEvent]([EventType], [Timestamp], [UserName], [ApplicationId])
values (@0, @1, @2, @3)
select [Id]
from [dbo].[AuditEvent]
where @@ROWCOUNT > 0 and [Id] = scope_identity()',N'@0 nvarchar(10),@1 datetimeoffset(7),@2 nvarchar(11),@3 nvarchar(36)',@0=N'UpdateUser',@1='2009-11-10 10:58:33.2814740 +01:00',@2=N'foo',@3=N'bar'

这解释了为什么需要 SELECT权限,因为该操作返回插入行的自动生成的ID。

现在的问题仍然存在:我不需要知道刚刚插入的行的ID,所以有什么方法可以关闭此功能吗?

2 个答案:

答案 0 :(得分:8)

默认情况下,在向ObjectContext添加实体并调用SaveChanges后,该对象的状态将从Added更改为Unchanged,并且仍由ObjectContext跟踪。这就是EF需要该ID以便能够跟踪其变化的原因。

Entity Keys and added objects:

  

1.构造实体对象。   此时关键属性全部   有默认值,null或0。

     

2.新对象被添加到   ObjectContext要么通过调用   AddObject或其中一个实体   特定于集合的添加方法   上下文或通过调用添加   返回一个导航属性   EntityCollection。

     

此时,对象服务   生成一个临时密钥,即   用于存储对象   ObjectStateManager。

     

3.SaveChanges被调用   ObjectContext的。

     

生成INSERT语句   实体服务并在上面执行   数据来源。

     

4.如果INSERT操作成功,   服务器生成的值被写入   回到ObjectStateEntry。

     

5. ObjectStateEntry更新   用服务器生成的对象   值。

     

6.当调用AcceptChanges时   ObjectStateEntry,一个永久物   EntityKey使用new计算   服务器生成的值。

所以,据我所知,不可能从ObjectContext切换这个功能,我没有看到任何“好”的解决方案来解决这个问题:一种避免这种情况的方法是使用你自己的存储过程插入实体(如果可以)(http://msdn.microsoft.com/en-us/library/bb399203.aspx)。

此外,如果没有服务器生成的ID,我认为不会执行选择查询(如果你可以改变dbs,再次,如果你想打扰id的生成)。

答案 1 :(得分:5)

然而,这是一个古老的问题,但未来也许任何人都会使用。一种方法是仅向id字段提供select权限。