简短的回答是没有能力,将允许授权用户从一个程序(即你的中间层)连接,而不是另一个(即一个交互式查询程序,如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
非常感谢你这样详细的回答!我试图在我的本地SQL数据库中为此构建一个测试,但是我继续获取'无法创建触发'CONNECTION_AUTHORIZATION_TRIGGER',因为您没有permission.'错误,尽管我已将所有权限授予了我的Windows登录。任何想法? –
您需要'CONTROL SERVER'或者是'sysadmin'才能创建'LOGON TRIGGER'。确保你是'sysadmin'的成员。 BTW。我看到的这类错误的一个根本原因是,通过成员身份授予机器管理员组('builtin \ Administrators')对'sysadmin'的访问权限;并且调用者未使用提升的提示连接到SQL Server(因此不是完整的管理员)。尝试使用完全管理(在cmd提示符上单击鼠标右键,然后选择“以管理员身份运行”)运行'sqlcmd'并在您的测试框中查看是否以完整的系统管理员身份执行此操作。 –