2010-06-30 78 views
2

我在使用混合模式身份驗證的Microsoft SQL Server 2008 Express實例中有一個名爲MyDB的數據庫。使用數據庫MyDB的應用程序當前使用Windows身份驗證使用當前用戶的Windows憑據進行連接。此登錄名是「公共」服務器角色的成員,並且有一個用戶映射到MyDB數據庫中。此數據庫用戶是db_datareader和db_datawriter數據庫角色的成員。在登錄觸發器內切換執行上下文

我想要的是,當應用程序連接時,它有權在MyDB中讀寫。但是當另一個應用程序使用相同的登錄連接時,應該只允許讀取它。

我的想法是,我會創建一個登錄觸發器,它將檢查連接字符串的應用程序名稱部分,並根據它決定是否應切換執行上下文。 (爲了記錄,我知道依賴連接字符串的應用程序名稱並不安全,並且很容易規避。此處的目的不是保護數據庫,而是爲了幫助用戶避免更改當他們使用其他應用程序(例如Microsoft Excel)連接時的數據)

我創建了一個名爲'myapp_reader'的新登錄映射到MyDB數據庫中的用戶,該用戶是db_datareader的成員。

然後我試着用下面的TSQL創建一個登錄觸發器:

CREATE TRIGGER CheckUser 
ON ALL SERVER 
AFTER LOGON AS 
BEGIN 
IF APP_NAME() <> 'My Application Name' 
    BEGIN 
     EXECUTE AS LOGIN = 'myapp_reader' WITH NO REVERT 
    END 
END 

但不幸的是,這是行不通的。當我嘗試連接,我得到以下錯誤:

Logon failed for login 'MyComputer\MyWindowsUsername' due to trigger execution.
Changed database context to 'master'.
Changed language setting to us_english. (Microsoft SQL Server, Error: 17892)

當我看在錯誤日誌,它說:

Error: 15590, Severity: 16, State: 1.
Can only use the 'No Revert' or 'Cookie' options with the 'Execute As' statement at the adhoc level.
Error: 17892, Severity: 20, State: 1.
Logon failed for login 'MyComputer\MyWindowsUsername' due to trigger execution. [CLIENT: xxx.xxx.xxx.xxx]

此錯誤意味着我永遠不能改變的執行上下文在登錄觸發器?

回答

1

我不認爲有可能改變整個會話的執行上下文。您可以爲數據庫中的每個表/視圖創建一個用於INSERT,UPDATE和DELETE的DML觸發器,它爲特定的app_name()執行回滾。你可以編寫一個程序來自動創建所有這些觸發器。

或者,如果您可以選擇通過鏈接服務器連接Excel等應用程序,那麼您可以在此處更改執行上下文。如果用戶嘗試通過Excel或其他應用程序直接連接到服務器,則創建一個登錄觸發器以回滾連接。

1

假設您可以控制應用程序並且可以對其進行修改,那麼應用程序角色將按照您的需要進行操作。請參閱聯機叢書中的sp_setapprole以開始使用。

+0

嗯,我想我會追求這種做法。謝謝! – 2010-08-20 13:10:17

0

你不能以你想要的方式做到這一點。

  • 除了使用EXECUTE AS的某些特定作用域外,用戶連接在整個過程中都具有相同的憑據。
  • 你已經意識到你不能依靠APP_NAME()或HOST_NAME()來檢測某人連接的方式不同,這意味着每個表的回滾觸發器不能依賴於那裏
  • 你的應用程序依賴於直接表寫入權限

我能想到的一些選擇...

  • 應用程序使用存儲的特效,用戶只能讀取該表
  • 使用SET CONTEXT_INFO在您的應用程序設置一個「祕密」回滾鍵觸發
  • 更改您的應用程序使用服務帳戶/是一個Windows服務的/ etc和代理的用戶名(如網頁會做)
  • ...或者一些排列therof
0

你真的需要讓你的心如何組織和管理憑證第一。

如果您使用sp_setapprole將規避Windows身份驗證並允許任何用戶通過該應用程序進行訪問。如果這就是您真正想要做的事情,那麼如果應用程序是服務器爲該應用程序創建用戶帳戶並在該用戶的憑據下運行該帳戶。

如果它是一個客戶端應用程序,然後建立一個Web服務,它將只讀取和發送應用程序需要的特定數據,並在新帳戶下運行該Web服務。然後,在IIS7中,您可以在Web服務上放置一個ACL,以便它仍然受到保護。

此外,如果該應用程序不被信任是乾淨的並且知道它在做什麼,那麼請求它在允許觸摸SQL服務器之前必須進行代碼審查。如果這是你自己的應用程序,然後開始相信自己:-)