我需要在sql server上使用应用程序规则安全性。我想使用Enity Framework Code First。带SQL服务器应用程序角色的EF
成功登录后,我的连接被设置为应用程序角色。然后我使用这个连接创建我的DbContext。
但是:EF期望一个封闭的连接对象。关闭连接会降低应用程序角色。
我该如何解决这个困境?
我需要在sql server上使用应用程序规则安全性。我想使用Enity Framework Code First。带SQL服务器应用程序角色的EF
成功登录后,我的连接被设置为应用程序角色。然后我使用这个连接创建我的DbContext。
但是:EF期望一个封闭的连接对象。关闭连接会降低应用程序角色。
我该如何解决这个困境?
我设法得到这个工作有两个步骤:
交换机连接池关闭,这是提到的所有时间使用应用程序角色的连接。由于我有桌面应用程序,这对我来说不成问题。
添加一个处理程序到DbConnection.StateChanged
并在连接的每个打开时激活应用程序角色。没有连接池,关闭时不需要sp_unsetapprole
。因此,这对我的作品:
context.Database.Connection.StateChanged += (sender, args) =>
if (args.CurrentState == ConnectionState.Open) {
activateAppRole((DbConnection)sender, ...);
}
}
我想,如果池是非常重要的人,她可以叫sp_unsetapprole
在关闭这个相同的处理程序的连接。
EF对此没有任何本机支持。我想解决方法可以是:
由于这个问题在搜索结果列表中很高,我只想提出一个谨慎的话。我有一个应用程序需要使用应用程序角色,并且okrumnow的解决方案似乎首先起作用。
然而,在单元测试我发现,有时候处理StateChanged事件将导致两次上调的情况下,你会得到错误:
"Impersonate Session Security Context" cannot be called in this batch because a simultaneous batch has called it.
这似乎有助于条件更改为:
args.CurrentState == ConnectionState.Open &&
args.CurrentState == ConnectionState.Closed
但它仍然不能消除错误。我在EF4.3和EF5中证实了这一点。 Ladislav正确的是,理想的方式是为DbContext创建一个连接并告诉上下文它不拥有它。
此外,由于没有ConnectionState.Closing
事件,因此在连接关闭之前可以拨打sp_unsetapprole
,因此连接池永远不可能使用此设置。
由于我具有灵活性,我的解决方案是消除应用程序角色的使用并使用专用的SQL登录。无论哪种方式,你是硬编码的密码...
不幸的是,DbContext总是打开和关闭连接,所以你的猜测不起作用。 – okrumnow