2016-09-29 69 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'并在您的测试框中查看是否以完整的系统管理员身份执行此操作。 –