2011-11-17 20 views
3

我需要在sql server上使用應用程序規則安全性。我想使用Enity Framework Code First。帶SQL服務器應用程序角色的EF

成功登錄後,我的連接被設置爲應用程序角色。然後我使用這個連接創建我的DbContext。

但是:EF期望一個封閉的連接對象。關閉連接會降低應用程序角色。

我該如何解決這個困境?

回答

6

我設法得到這個工作有兩個步驟:

交換機連接池關閉,這是提到的所有時間使用應用程序角色的連接。由於我有桌面應用程序,這對我來說不成問題。

添加一個處理程序到DbConnection.StateChanged並在連接的每個打開時激活應用程序角色。沒有連接池,關閉時不需要sp_unsetapprole。因此,這對我的作品:

context.Database.Connection.StateChanged += (sender, args) => 
    if (args.CurrentState == ConnectionState.Open) { 
    activateAppRole((DbConnection)sender, ...); 
    } 
} 

我想,如果池是非常重要的人,她可以叫sp_unsetapprole在關閉這個相同的處理程序的連接。

0

EF對此沒有任何本機支持。我想解決方法可以是:

  • 創建您自己的連接並將它傳遞(關閉)到EF上下文/ EntityConnection。這應該強制您將在您的控制下有連接生命週期,並且EF不會關閉它(但我已經看到抱怨說它不適用於DbContext)。
  • 一旦您創建了上下文創建的設置應用程序角色的實例。上下文本身不應該對數據庫產生任何查詢(除了代碼首先檢查數據庫版本的DbContext除外),所以在創建上下文後設置角色不應引起任何問題。
+0

不幸的是,DbContext總是打開和關閉連接,所以你的猜測不起作用。 – okrumnow

4

由於這個問題在搜索結果列表中很高,我只想提出一個謹慎的話。我有一個應用程序需要使用應用程序角色,並且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登錄。無論哪種方式,你是硬編碼的密碼...

相關問題