2016-09-29 67 views
0

我們有一個運行SQL Server數據庫的MVC應用程序。防止數據庫在應用程序外訪問

我們使用Windows身份驗證,而當我們想給用戶到我們的網站訪問我們的活動目錄組SEUser中添加它們。

我們已經給出的登錄以及訪問權限設置爲SEUser組到我們的數據庫也是如此。

但問題是,因爲在AD組有權限的數據庫,以便屬於該組不僅可以訪問網站,但也可以從應用程序外連接到數據庫,並可以進行更改,以及用戶。

所以我搜索了很多找到任何辦法,我可以限制用戶組訪問數據庫,只有當請求通過我們的應用程序,而不是從外面。

對於我想到的第一種方法是使用模擬/連接的方法,並且只允許工作進程帳戶連接到數據庫,

但問題是,我們正在訪問當前登錄的用戶信息中存儲過程也使用類似SYSTEM_USERIS_MEMBER這樣的方法,它只考慮當前登錄用戶,因此我們不能使用工作進程方法。

有什麼辦法可以達到我的特殊情況?請幫助

回答

2

簡短的回答是沒有能力,將允許授權用戶從一個程序(即你的中間層)連接,而不是另一個(即一個交互式查詢程序,如SSMS)。

我可以給你的最好的建議是設計你的系統,假設用戶會找到一種方法直接連接到數據庫,並因此儘可能限制他們的權限,以避免任何問題,當他們決定這樣做。

限制用戶在直接連接到數據庫時可以在系統上執行的操作的一種策略是使用存儲過程來限制他們應該能夠在數據庫上執行的操作(即他們有權訪問運行SP,其他),只通過簽名的SP執行來授予權限。

我也強烈建議使用審計來檢測濫用用戶的權限。鑑於您期望所有用戶通過您的中間層應用程序連接,檢測異常活動應該相對容易。作爲一種解決方法是使用登錄你可能會發現有趣的

一招觸發要儘量避免通過非授權程序的意外訪問(AKA,避免了「我不知道」的藉口)。但要警告:這不是安全邊界,很容易繞過,但它會幫助你保持誠實的人誠實。

例如:

我授權給特定組我的系統上,但我想限制這一羣體儘可能多的給我的應用程序:

CREATE LOGIN [myDomain\myGroup] FROM WINDOWS 

所以我將創建登錄觸發器將檢查會話上的應用程序名稱,並阻止任何我沒有爲這些用戶批准的應用程序。

CREATE TRIGGER connection_limit_trigger 
ON ALL SERVER 
FOR LOGON 
AS 
BEGIN 
IF(IS_SRVROLEMEMBER('sysadmin') != 1) 
BEGIN 
    IF(IS_MEMBER('myDomain\myGroup') = 1) 
    BEGIN 
     DECLARE @appName nvarchar(256) 
     SELECT @appName = program_name FROM sys.dm_exec_sessions where session_id = @@SPID 
     IF(@appName != 'My approved app') 
      ROLLBACK; 
    END 
END 
END; 

請注意,此觸發器會影響我的所有用戶,所以我添加了檢查以避免對某些用戶造成不必要的限制。

我有一個非常簡單的應用程序,我批准(參見連接字符串ApplicationName屬性):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data; 
using System.Data.SqlClient; 

namespace SampleAppSql 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      SqlConnectionStringBuilder cnnstrbldr = new SqlConnectionStringBuilder(); 
      cnnstrbldr.ApplicationName = @"My approved app"; 
      cnnstrbldr.DataSource = @"."; //local machine 
      cnnstrbldr.IntegratedSecurity = true; 

      using (SqlConnection conn = new SqlConnection(cnnstrbldr.ConnectionString)) 
      { 
       conn.Open(); 
       using (SqlCommand cmd = conn.CreateCommand()) 
       { 
        cmd.CommandText = @"SELECT @@version;"; 
        string vers = (string)cmd.ExecuteScalar(); 
        System.Console.WriteLine(@"SQL Server version: {0}", vers); 
       } 
       conn.Close(); 
      } 
     } 
    } 
} 

當這個組的用戶試圖連接到SQL Server,觸發將檢查應用程序名稱,如果不匹配,登錄觸發器會導致連接失敗:

C:\>g:\temp\SampleAppSql.exe 
SQL Server version: Microsoft SQL Server 2016 (RTM) … 

C:\>sqlcmd -E -S . 
Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Logon failed for login 'myDomain\toto' due to trigger execution.. 

請注意,這種技術不是一個安全邊界,作爲授權用戶可以簡單操作的應用程序名稱和旁路觸發;但違規用戶將無法否認她/他故意試圖繞過您的政策。

我希望這些信息對您有所幫助。

有關詳細信息,我推薦以下相關文章:在SQL Server(https://msdn.microsoft.com/en-us/library/bb669102(v=vs.110).aspx

  • 自定義權限在SQL Server中模擬

    -Raul

  • +0

    非常感謝你這樣詳細的回答!我試圖在我的本地SQL數據庫中爲此構建一個測試,但是我繼續獲取'無法創建觸發'CONNECTION_AUTHORIZATION_TRIGGER',因爲您沒有permission.'錯誤,儘管我已將所有權限授予了我的Windows登錄。任何想法? –

    +0

    您需要'CONTROL SERVER'或者是'sysadmin'才能創建'LOGON TRIGGER'。確保你是'sysadmin'的成員。 BTW。我看到的這類錯誤的一個根本原因是,通過成員身份授予機器管理員組('builtin \ Administrators')對'sysadmin'的訪問權限;並且調用者未使用提升的提示連接到SQL Server(因此不是完整的管理員)。嘗試使用完全管理(在cmd提示符上單擊鼠標右鍵,然後選擇「以管理員身份運行」)運行'sqlcmd'並在您的測試框中查看是否以完整的系統管理員身份執行此操作。 –

    相關問題