我需要在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