存储过程中的屏蔽列
Masking column in stored procedure
首先,作为 SQL 服务器的管理员,我正在尝试使用标准数据库来屏蔽列。
CREATE TABLE [Person].[MyEmailAddress]
(
[MyBusinessEntityID] [int] NOT NULL,
[MyEmailAddressID] [int] IDENTITY(1,1) NOT NULL,
[EmailAddress] [nvarchar](50) MASKED WITH (FUNCTION = 'email()') NULL, --<== masked
[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_MyEmailAddress_BusinessEntityID_EmailAddressID] PRIMARY KEY CLUSTERED (
[MyBusinessEntityID] ASC,
[MyEmailAddressID] ASC
)
) ON [PRIMARY]
GO
然后,我创建了一个新的存储过程
CREATE PROCEDURE [Person].[Email_Address]
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT * from [Person].[EmailAddress]
END
GO
然后,我创建了一个新的登录用户
create login AdvUserTest004
with password = 'Test123'
create user User004
for login AdvUserTest004
-- add user to the database owner role
exec sp_addrolemember N'db_owner', N'User004'
通过将此 link 引用到 db_datawriter
和 db_datareader
来设置用户角色。没有这两个成员资格,表格就不会出现。
然后,我尝试使用 'AdvUserTest004' 和 SQL 服务器身份验证模式登录。试图执行 select 语句
select * from [Person].[EmailAddress]
输出结果看起来不错,屏蔽了。
但是上面的存储过程没有出现。因此,通过引用此document,授予执行权限。
现在,存储过程照常出现。然后,执行存储过程
exec [Person].[Email_Address]
结果如下所示:
所以问题是,
- 为什么在存储过程中执行时电子邮件列 未屏蔽 但在 select 语句中被屏蔽?
- email 列在存储过程中执行时应该如何屏蔽?
您正在使您的用户成为 db_owner
。如果你勾选 Chart of SQL Server Permissions:
可以看到这个角色的成员可以UNMASK
任何数据。这可以很容易地用下面的代码检查:
DROP TABLE IF EXISTS [dbo].[Whosebug];
CREATE TABLE [dbo].[Whosebug]
(
[email] NVARCHAR(128) MASKED WITH (FUNCTION = 'email()')
);
INSERT INTO [dbo].[Whosebug] ([email])
VALUES ('text1@gmail.bg')
,('text2@gmail.bg')
,('text3@gmail.bg');
SELECT [email]
FROM [dbo].[Whosebug];
GO
DROP USER IF EXISTS [Daleman];
CREATE USER [Daleman] WITHOUT LOGIN;
GRANT SELECT ON [dbo].[Whosebug] TO [Daleman];
GO
EXECUTE AS USER = 'Daleman';
SELECT [email]
FROM [dbo].[Whosebug];
REVERT;
GO
EXEC sp_addrolemember N'db_owner', N'Daleman';
EXECUTE AS USER = 'Daleman';
SELECT [email]
FROM [dbo].[Whosebug];
REVERT;
我在哪里:
- 创建一个新的 table 并查询它(因为我
sys.admin
我可以 unmask
)
- 创建一个有权查询 table 的新用户(不能
unmask
并查看被屏蔽的数据)
- 制作用户
db_owner
并显示现在用户可以看到原始数据
这里是执行代码的输出:
所以,我猜你没有正确测试你看到数据被屏蔽的情况。
我刚从这个 link
中得到示例
-- Demonstrate Dynamic Data Masking
--
-- Make sure to connect using a privileged user such as the database owner or sysadmin
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'GreatLakesUser')
BEGIN
CREATE LOGIN GreatLakesUser
WITH PASSWORD = N'SQLRocks!00',
CHECK_POLICY = OFF,
CHECK_EXPIRATION = OFF,
DEFAULT_DATABASE = WideWorldImporters;
END;
GO
USE WideWorldImporters;
GO
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = N'GreatLakesUser')
BEGIN
CREATE USER GreatLakesUser FOR LOGIN GreatLakesUser;
END;
GO
ALTER ROLE [Great Lakes Sales] ADD MEMBER GreatLakesUser;
GO
-- grant SELECT rights to role principal
GRANT SELECT ON Purchasing.Suppliers TO [Great Lakes Sales];
GO
-- select with current UNMASK rights (NOTE row count and data values), assuming you are connected using a privileged user
SELECT SupplierID, SupplierName, BankAccountName, BankAccountBranch, BankAccountCode, BankAccountNumber FROM Purchasing.Suppliers;
-- impersonate the user GreatLakesUser
EXECUTE AS USER = 'GreatLakesUser';
GO
-- select with impersonated MASKED rights (NOTE row count and data values)
SELECT SupplierID, SupplierName, BankAccountName, BankAccountBranch, BankAccountCode, BankAccountNumber FROM Purchasing.Suppliers;
GO
REVERT;
GO
-- Clean-up (optional)
/*
REVOKE SELECT ON Purchasing.Suppliers TO [Great Lakes Sales];
GO
DROP USER GreatLakesUser;
GO
DROP LOGIN GreatLakesUser;
GO
*/
首先,作为 SQL 服务器的管理员,我正在尝试使用标准数据库来屏蔽列。
CREATE TABLE [Person].[MyEmailAddress]
(
[MyBusinessEntityID] [int] NOT NULL,
[MyEmailAddressID] [int] IDENTITY(1,1) NOT NULL,
[EmailAddress] [nvarchar](50) MASKED WITH (FUNCTION = 'email()') NULL, --<== masked
[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_MyEmailAddress_BusinessEntityID_EmailAddressID] PRIMARY KEY CLUSTERED (
[MyBusinessEntityID] ASC,
[MyEmailAddressID] ASC
)
) ON [PRIMARY]
GO
然后,我创建了一个新的存储过程
CREATE PROCEDURE [Person].[Email_Address]
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT * from [Person].[EmailAddress]
END
GO
然后,我创建了一个新的登录用户
create login AdvUserTest004
with password = 'Test123'
create user User004
for login AdvUserTest004
-- add user to the database owner role
exec sp_addrolemember N'db_owner', N'User004'
通过将此 link 引用到 db_datawriter
和 db_datareader
来设置用户角色。没有这两个成员资格,表格就不会出现。
然后,我尝试使用 'AdvUserTest004' 和 SQL 服务器身份验证模式登录。试图执行 select 语句
select * from [Person].[EmailAddress]
输出结果看起来不错,屏蔽了。
但是上面的存储过程没有出现。因此,通过引用此document,授予执行权限。
现在,存储过程照常出现。然后,执行存储过程
exec [Person].[Email_Address]
结果如下所示:
所以问题是,
- 为什么在存储过程中执行时电子邮件列 未屏蔽 但在 select 语句中被屏蔽?
- email 列在存储过程中执行时应该如何屏蔽?
您正在使您的用户成为 db_owner
。如果你勾选 Chart of SQL Server Permissions:
可以看到这个角色的成员可以UNMASK
任何数据。这可以很容易地用下面的代码检查:
DROP TABLE IF EXISTS [dbo].[Whosebug];
CREATE TABLE [dbo].[Whosebug]
(
[email] NVARCHAR(128) MASKED WITH (FUNCTION = 'email()')
);
INSERT INTO [dbo].[Whosebug] ([email])
VALUES ('text1@gmail.bg')
,('text2@gmail.bg')
,('text3@gmail.bg');
SELECT [email]
FROM [dbo].[Whosebug];
GO
DROP USER IF EXISTS [Daleman];
CREATE USER [Daleman] WITHOUT LOGIN;
GRANT SELECT ON [dbo].[Whosebug] TO [Daleman];
GO
EXECUTE AS USER = 'Daleman';
SELECT [email]
FROM [dbo].[Whosebug];
REVERT;
GO
EXEC sp_addrolemember N'db_owner', N'Daleman';
EXECUTE AS USER = 'Daleman';
SELECT [email]
FROM [dbo].[Whosebug];
REVERT;
我在哪里:
- 创建一个新的 table 并查询它(因为我
sys.admin
我可以unmask
) - 创建一个有权查询 table 的新用户(不能
unmask
并查看被屏蔽的数据) - 制作用户
db_owner
并显示现在用户可以看到原始数据
这里是执行代码的输出:
所以,我猜你没有正确测试你看到数据被屏蔽的情况。
我刚从这个 link
中得到示例-- Demonstrate Dynamic Data Masking
--
-- Make sure to connect using a privileged user such as the database owner or sysadmin
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'GreatLakesUser')
BEGIN
CREATE LOGIN GreatLakesUser
WITH PASSWORD = N'SQLRocks!00',
CHECK_POLICY = OFF,
CHECK_EXPIRATION = OFF,
DEFAULT_DATABASE = WideWorldImporters;
END;
GO
USE WideWorldImporters;
GO
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = N'GreatLakesUser')
BEGIN
CREATE USER GreatLakesUser FOR LOGIN GreatLakesUser;
END;
GO
ALTER ROLE [Great Lakes Sales] ADD MEMBER GreatLakesUser;
GO
-- grant SELECT rights to role principal
GRANT SELECT ON Purchasing.Suppliers TO [Great Lakes Sales];
GO
-- select with current UNMASK rights (NOTE row count and data values), assuming you are connected using a privileged user
SELECT SupplierID, SupplierName, BankAccountName, BankAccountBranch, BankAccountCode, BankAccountNumber FROM Purchasing.Suppliers;
-- impersonate the user GreatLakesUser
EXECUTE AS USER = 'GreatLakesUser';
GO
-- select with impersonated MASKED rights (NOTE row count and data values)
SELECT SupplierID, SupplierName, BankAccountName, BankAccountBranch, BankAccountCode, BankAccountNumber FROM Purchasing.Suppliers;
GO
REVERT;
GO
-- Clean-up (optional)
/*
REVOKE SELECT ON Purchasing.Suppliers TO [Great Lakes Sales];
GO
DROP USER GreatLakesUser;
GO
DROP LOGIN GreatLakesUser;
GO
*/