暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL Server行级安全性

原创 eternity 2022-08-15
627

在今天的文章中,我们将研究SQL Server行级安全性。

在IT世界中,安全性非常重要。在数据库安全方面,这一点至关重要。因为数据库包含其所在组织的所有数据和信息。

想想看,你在一家电子商务公司工作,数据库中有很多信息,比如客户信息、订单、付款。

监控并确保这些信息的安全性是DBA(数据库管理员)最重要的职责之一。在本文中,我将讨论我们通过SQL Server 2016获得的安全和加密解决方案,这些解决方案将包含在下一个版本中。

请记住,在KVKK端的某个时候,您还需要这里的功能。如果您想自己应用本文中的示例,您的系统上必须至少安装SQL Server 2017。

您可以选择开发者版作为免费版。我的系统上安装了SQL Server 2019开发者版。

什么是SQL Server行级安全性?

行级安全性是SQL Server中一项长期要求的功能,Microsoft在SQL Server 2016中引入了它。您可以在SQL Server 16和所有更高版本(Express、Standard和Enterprise)中使用此功能。

行级安全性(RLS)满足了许多客户的许多业务需求。因此,我们可以生成许多关于行级安全性的场景。

首先,当您的所有客户都在同一张表中,销售人员可以根据该表进行报告,而不必查看其他客户的数据时,这是一个重要的需求。

举一个不同的例子,假设医院里有一名护士。可能需要确保该护士只能看到自己患者的数据,而不能看到不同护士的数据。

正如我给出的示例,您可能正在通过思考如何将其应用于您自己的应用程序来生成场景。这就是为什么行级安全—行级安全性—允许您配置表。

因此,用户只能看到被授予访问权限的行。在正常情况下,要执行此操作,必须在应用程序级别对执行操作的人员应用where条件限制。

但是,在执行插入、更新和删除操作时,您需要生成不同的业务流程,以确保它仅在其自身的限制范围内运行。这就是SQL Server 2016中的行级安全性(RLS)最适合您的地方。

SQL Server行级安全性的脚注:此功能将为您提供基于会话的安全性。

让我们就上面提到的几个例子解释一下我们是如何使用这个特性的。

例1:你是一名商店员工,你想看看一天结束时你的销售额。

在本文中,我将使用我们创建的名为“DMC_SQLSecurity”的数据库,并给出一个示例。当您在自己的方面实现它时,不要忘记更改它。

为了在示例中使用它,我需要创建1个销售经理和2个销售代表。

Use DMC_SQLSecurity
 
go
 
CREATE USER Salesmanager WITHOUT LOGIN;
 
CREATE USER SalesRepresentative1 WITHOUT LOGIN;
 
CREATE USER SalesRepresentative2 WITHOUT LOGIN;

我创建了我需要的用户。现在我需要下一张销售表。让我们用下面的代码创建它。

CREATE TABLE Sales
 
(
 
Id int,
 
Seller sysname,
 
product varchar(10),
 
piece int
 
);

创建sales表后,让我们使用以下代码添加一条记录。

INSERT INTO Sales VALUES
 
(1, 'SalesRepresentative1', 'Notebook', 5),
 
(2, 'SalesRepresentative1', 'PC', 2),
 
(3, 'SalesRepresentative1', 'Monitor', 4),
 
(4, 'SalesRepresentative2', 'Phone', 2),
 
(5, 'SalesRepresentative2', 'HDMI cable', 5),
 
(6, 'SalesRepresentative2', 'Chair', 5);

让我们看看记录被添加了。

SELECT * FROM Sales;

微信图片_20220814154303.png

让我们为我们创建的用户提供“选择”授权,以便他们可以查看Sales表上的数据。

GRANT SELECT ON Sales TO SalesManager;
 
GRANT SELECT ON Sales TO SalesRepresentative1;
 
GRANT SELECT ON Sales TO SalesRepresentative2;
GO

当我们查询sales表时,我们看到我们的两位销售代表都收到了数据。

现在,我们将使用SQL Server行级安全性–RLS–功能来确保销售代表只能查看其销售额。为此,我们需要一个内联表值函数来返回真值。

CREATE OR ALTER FUNCTION dbo.fn_RLS (@Seller AS sysname)
 
RETURNS TABLE
 
WITH SCHEMABINDING
 
AS
 
RETURN SELECT 1 AS fn_RLS_Result
 
WHERE @SalesMaker = USER_NAME() OR USER_NAME() = 'SalesManager';
 
GO

在这个过程之后,我们需要创建一个策略来过滤我们创建的内联函数。

CREATE SECURITY POLICY SalesFilter
 
ADD FILTER PREDICATE dbo.fn_RLS(Salesmaker)
 
ON dbo.Sales
 
WITH (STATE = ON);

如果我们检查我们创建的功能和策略代码;如我们所见,我们的函数将用户名作为参数,并返回True和NULL值。

在我们的策略部分中,我们指定了名为fn_RLS的函数,我们在PRADICATE部分中创建了该函数,该函数将用于在查询在我们的表上运行时自动过滤,以及在哪个表上执行该操作。

现在,在这些定义之后,让我们查询一下Sales表。

We are querying the sales table with SalesRepresentative1
 
EXECUTE AS USER = 'SalesRepresentative1';
 
SELECT *,USER_NAME() USerName FROM Sales;
 
REVERT;
 
-- We are querying the sales table with SalesRepresentative2
 
EXECUTE AS USER = 'SalesRepresentative2';
 
SELECT *,USER_NAME() USerName FROM Sales;
 
REVERT;
 
-- We are querying the Sales table with the Sales Manager
 
EXECUTE AS USER = 'SalesManager';
 
SELECT *,USER_NAME() USerName FROM Sales;
 
REVERT;

微信图片_20220814154543.png

事实上,如果要与连接的用户一起查询Sales表并执行交易,则不会看到记录。

SELECT * FROM Sales;

微信图片_20220814154710.png

那么销售表是空的吗?当然,当适合卖方信息的用户进来时,select查询的结果会返回。

如果您立即想到如何在SQL Server 2016之前的版本中实现此功能,让我们用下面的示例解释答案。

如何在SQL Server 2016之前实现行级安全?

我们在上面给出了一个关于行级安全性使用的示例,现在让我们通过相同的示例主题解释如何在SQL Server 2016之前使用它。让我们的销售代表和销售经理保持一致。

在开始处理该示例之前,让我们先放下在RLS示例中创建的Satis表。在退出之前,我们需要关闭我们创建的策略。

DROP SECURITY POLICY [dbo].[SalesFilter]
 
GO
 
Drop Table Sales

我们已经完成了下降,现在我们可以再次开始为我们的示例工作。对于类似的示例,让我们创建Sales表并向其中添加示例记录。

CREATE TABLE SALES
 
(
 
id int,
 
Seller sysname,
 
Product varchar(10),
 
Quantity int
 
);
 
INSERT INTO Sales VALUES
 
(1, 'SalesRepresentative1', 'Server', 5),
 
(2, 'SalesRepresentative1', 'MousePad', 2),
 
(3, 'SalesRepresentative1', 'Mouse', 4),
 
(4, 'SalesRepresentative2', 'Mask', 2),
 
(5, 'SalesRepresentative2', 'Wallet', 5)

让我们查询sales表。

SELECT * FROM Sales;

微信图片_20220814154900.png

我们需要一个用户映射表,因为我们不能使用RLS功能。

CREATE TABLE SQLUserMapping
 
(CustomerID VARCHAR(5),
 
SQLUserName sysname,
 
Active Bit
 
CONSTRAINT PK_SQLUserMapping PRIMARY KEY (CustomerID, SQLUserName));
 
GO

让我们向映射表添加一条记录。

INSERT INTO SQLUserMapping (CustomerID, SQLUserName, Active)
 
VALUES('DMC01', 'SalesRepresentative1', 1)
 
GO

现在,让我们创建一个视图,在该视图中,我们将匹配Sales表和映射表,并报告销售额。

CREATE OR ALTER VIEW v_Sales
 
AS
 
SELECT Sales*
 
FROM Sales
 
JOIN SQLUserMapping on Satis.SalesMaker = SQLUserMapping.SQLUserName
 
AND SQLUserMapping.SQLUserName = USER_NAME()
 
GO

我们给我们之前定义的用户提供了一个名为v_satis的视图。

GRANT SELECT ON v_Satis TO SalesManager;
 
GRANT SELECT ON v_Satis TO SalesRepresentative1;
 
GRANT SELECT ON v_Satis TO SalesRepresentative2;

定义授权后,让我们使用用户satisrepresentation1查询Satis表和名为v_Satis的视图。

EXECUTE AS USER = 'SalesRepresentative1';
 
SELECT *,USER_NAME() USerName FROM sales;
 
REVERT;

微信图片_20220814155125.png

如上图所示,我们的用户没有查看销售表的权限。现在让我们查询v_ satis。

EXECUTE AS USER = 'SalesRepresentative1';
 
SELECT *,USER_NAME() USerName FROM v_Sales;
 
REVERT;

让我们向我们的销售代表2和SalesManagement用户查询v_satis

EXECUTE AS USER = 'SalesRepresentative2';
 
SELECT *,USER_NAME() USerName FROM v_sales;
 
REVERT;

微信图片_20220814163119.png

EXECUTE AS USER = 'SalesManager';
 
SELECT *,USER_NAME() USerName FROM v_sales;
 
REVERT;

微信图片_20220814163147.png
如图7和图8所示,查询结果为空,原因是我们在视图中创建的映射定义。如果更改Sales Manager的视图,则Sales representative1可以查看交易。

CREATE OR ALTER VIEW v_sales
 
AS
 
SELECT Sales*
 
FROM Sales
 
JOIN SQLUserMapping on sales.SalesMaker = SQLUserMapping.SQLUserName
 
AND SQLUserMapping.SQLUserName = USER_NAME() OR USER_NAME() = 'SalesManager'
 
GO

我们再次向销售经理提问。

EXECUTE AS USER = 'SalesManager';
 
SELECT *,USER_NAME() USerName FROM v_sales;
 
REVERT;

微信图片_20220814163449.png

原文标题:SQL Server Row Level Security
原文作者:Çağlar Özenç
原文链接:https://dbtut.com/index.php/2022/07/28/sql-server-row-level-security

最后修改时间:2022-08-16 12:56:32
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论