Entify Framework插入需要选择权限

Mar*_*ann 10 .net security linq-to-entities entity-framework 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();
Run Code Online (Sandbox Code Playgroud)

为什么我们需要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'
Run Code Online (Sandbox Code Playgroud)

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

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

Mis*_* N. 8

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

实体密钥和添加的对象:

1.构造实体对象.此时,键属性都具有默认值,null或0.

2.通过在上下文中调用AddObject或其中一个特定于实体集的add方法,或者通过在返回EntityCollection的导航属性上调用Add,将新对象添加到ObjectContext.

此时,对象服务生成一个临时密钥,用于在ObjectStateManager中存储对象.

3.SaveChanges在ObjectContext上调用.

INSERT语句由实体服务生成,并在数据源上执行.

4.如果INSERT操作成功,则将服务器生成的值写回ObjectStateEntry.

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

6.当在ObjectStateEntry上调用AcceptChanges时,将使用新的服务器生成的值计算永久的EntityKey.

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

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


use*_*899 5

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