如何将动态数据屏蔽与 FOR XML PATH 和子查询一起使用
How to use Dynamic Data Masking with FOR XML PATH and subqueries
我正在尝试从数据库生成 XML 并使用动态数据屏蔽来隐藏敏感信息,但是当我执行生成 XML 的存储过程时,用户应该只查看屏蔽数据,完成的 XML 缺少子查询的输出,只生成 <masked />
而不是通常的标签和该标签的内容。当我 运行 作为我的常规数据库用户的存储过程时,我得到了我需要的 XML-结果。
我已经尝试更改我的“蒙面数据库用户”的权限,但我无法解决问题。
这是我的存储过程的内容:
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.role
FROM dbo.UserRole ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.[User] u
INNER JOIN dbo.LegalCareUnit lcu
ON u.legalCareUnitId = lcu.id
WHERE lcu.legalCareUnitId = @LegalCareUnitId
FOR XML PATH ('user'), ROOT ('users')
以及由我的 常规数据库用户执行时的输出示例,即。没有动态数据屏蔽:
<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>111</identityNumber>
<firstName>Paddy</firstName>
<lastName>Smith</lastName>
<userRoles xmlns="urn:svsys:export:user">
<role>testRole</role>
</userRoles>
</user>
</users>
以及 XML 以我的 屏蔽数据库用户(使用动态数据屏蔽)执行时的外观:
<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>xxx</identityNumber>
<firstName>Paxxx</firstName>
<lastName>Smxxx</lastName>
<masked xmlns="" />
</user>
</users>
当以我的 masked 数据库用户(使用动态数据屏蔽):
执行时,我想得到什么
<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>xxx</identityNumber>
<firstName>Paxxx</firstName>
<lastName>Smxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<role>texxxxxx</role>
</userRoles>
</user>
</users>
如您所见,我第一个示例中的标签 <userRoles xmlns="urn:svsys:export:user">
在第二个示例中被 <masked xmlns="" />
替换。
知道如何在子标签 <role>
中获取带有屏蔽信息的标签 <userRoles>
吗?
测试设置
CREATE TABLE dbo.[TestUser]
(
id INT PRIMARY KEY IDENTITY(1,1),
userId INT NOT NULL,
identityNumber NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(4, "0101", 0)') NOT NULL,
firstName NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL,
lastName NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL
)
CREATE TABLE dbo.TestUserRole
(
id INT PRIMARY KEY IDENTITY(1,1),
userId INT NOT NULL,
userRole NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL
)
ALTER TABLE [dbo].[TestUserRole] WITH CHECK ADD CONSTRAINT [FK_TestUser_UserRole] FOREIGN KEY([userId])
REFERENCES [dbo].[User] ([id])
SET IDENTITY_INSERT TestUser ON
INSERT INTO TestUser (id, userId, identityNumber, firstName, lastName)
VALUES (1, 200, N'19520102', N'Paddy', N'Smith'),
(2, 300, N'19500609', N'Trevor', N'Bolder'),
(3, 400, N'19460526', N'Mick', N'Ronson')
SET IDENTITY_INSERT TestUser OFF
INSERT INTO TestUserRole (userId, userRole)
VALUES (1, N'Roadie'),
(2, N'Bassist'),
(3, N'Guitarist'),
(3, N'Pianist')
GO
CREATE PROCEDURE [dbo].TestGetUserRecordXml
AS
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.userRole
FROM dbo.TestUserRole ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.TestUser u
FOR XML PATH ('user'), ROOT ('users')
GO
CREATE USER [UserForMaskedData] WITHOUT LOGIN;
GRANT EXECUTE ON SCHEMA::dbo TO UserForMaskedData;
GRANT SELECT ON SCHEMA::dbo TO UserForMaskedData;
从 Microsoft Docs (https://docs.microsoft.com/en-us/answers/questions/526979/generating-xml-from-sql-with-dynamic-data-masking.html) 的 Erland Sommarskog 那里得到答案
为了使掩码在子查询中正常工作,必须将其放入临时 table,因此存储过程应如下所示:
SELECT * INTO #testis FROM TestUserRole;
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.userRole
FROM #testis ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.TestUser u
FOR XML PATH ('user'), ROOT ('users')
当以用户 UserForMaskedData 身份执行存储过程时,我得到了我想要的结果:
<users xmlns="urn:svsys:export:user">
<user>
<userId>200</userId>
<identityNumber>19520101</identityNumber>
<firstName>Paxxxxxxxxx</firstName>
<lastName>Smxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Roxxxxxxxxx</userRole>
</userRoles>
</user>
<user>
<userId>300</userId>
<identityNumber>19500101</identityNumber>
<firstName>Trxxxxxxxxx</firstName>
<lastName>Boxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Baxxxxxxxxx</userRole>
</userRoles>
</user>
<user>
<userId>400</userId>
<identityNumber>19460101</identityNumber>
<firstName>Mixxxxxxxxx</firstName>
<lastName>Roxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Guxxxxxxxxx</userRole>
<userRole>Pixxxxxxxxx</userRole>
</userRoles>
</user>
</users>
我正在尝试从数据库生成 XML 并使用动态数据屏蔽来隐藏敏感信息,但是当我执行生成 XML 的存储过程时,用户应该只查看屏蔽数据,完成的 XML 缺少子查询的输出,只生成 <masked />
而不是通常的标签和该标签的内容。当我 运行 作为我的常规数据库用户的存储过程时,我得到了我需要的 XML-结果。
我已经尝试更改我的“蒙面数据库用户”的权限,但我无法解决问题。
这是我的存储过程的内容:
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.role
FROM dbo.UserRole ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.[User] u
INNER JOIN dbo.LegalCareUnit lcu
ON u.legalCareUnitId = lcu.id
WHERE lcu.legalCareUnitId = @LegalCareUnitId
FOR XML PATH ('user'), ROOT ('users')
以及由我的 常规数据库用户执行时的输出示例,即。没有动态数据屏蔽:
<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>111</identityNumber>
<firstName>Paddy</firstName>
<lastName>Smith</lastName>
<userRoles xmlns="urn:svsys:export:user">
<role>testRole</role>
</userRoles>
</user>
</users>
以及 XML 以我的 屏蔽数据库用户(使用动态数据屏蔽)执行时的外观:
<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>xxx</identityNumber>
<firstName>Paxxx</firstName>
<lastName>Smxxx</lastName>
<masked xmlns="" />
</user>
</users>
当以我的 masked 数据库用户(使用动态数据屏蔽):
执行时,我想得到什么<users xmlns="urn:svsys:export:user">
<user>
<userId>2</userId>
<identityNumber>xxx</identityNumber>
<firstName>Paxxx</firstName>
<lastName>Smxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<role>texxxxxx</role>
</userRoles>
</user>
</users>
如您所见,我第一个示例中的标签 <userRoles xmlns="urn:svsys:export:user">
在第二个示例中被 <masked xmlns="" />
替换。
知道如何在子标签 <role>
中获取带有屏蔽信息的标签 <userRoles>
吗?
测试设置
CREATE TABLE dbo.[TestUser]
(
id INT PRIMARY KEY IDENTITY(1,1),
userId INT NOT NULL,
identityNumber NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(4, "0101", 0)') NOT NULL,
firstName NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL,
lastName NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL
)
CREATE TABLE dbo.TestUserRole
(
id INT PRIMARY KEY IDENTITY(1,1),
userId INT NOT NULL,
userRole NVARCHAR(50) MASKED WITH (FUNCTION = 'partial(2, "xxxxxxxxx", 0)') NOT NULL
)
ALTER TABLE [dbo].[TestUserRole] WITH CHECK ADD CONSTRAINT [FK_TestUser_UserRole] FOREIGN KEY([userId])
REFERENCES [dbo].[User] ([id])
SET IDENTITY_INSERT TestUser ON
INSERT INTO TestUser (id, userId, identityNumber, firstName, lastName)
VALUES (1, 200, N'19520102', N'Paddy', N'Smith'),
(2, 300, N'19500609', N'Trevor', N'Bolder'),
(3, 400, N'19460526', N'Mick', N'Ronson')
SET IDENTITY_INSERT TestUser OFF
INSERT INTO TestUserRole (userId, userRole)
VALUES (1, N'Roadie'),
(2, N'Bassist'),
(3, N'Guitarist'),
(3, N'Pianist')
GO
CREATE PROCEDURE [dbo].TestGetUserRecordXml
AS
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.userRole
FROM dbo.TestUserRole ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.TestUser u
FOR XML PATH ('user'), ROOT ('users')
GO
CREATE USER [UserForMaskedData] WITHOUT LOGIN;
GRANT EXECUTE ON SCHEMA::dbo TO UserForMaskedData;
GRANT SELECT ON SCHEMA::dbo TO UserForMaskedData;
从 Microsoft Docs (https://docs.microsoft.com/en-us/answers/questions/526979/generating-xml-from-sql-with-dynamic-data-masking.html) 的 Erland Sommarskog 那里得到答案
为了使掩码在子查询中正常工作,必须将其放入临时 table,因此存储过程应如下所示:
SELECT * INTO #testis FROM TestUserRole;
WITH XMLNAMESPACES (DEFAULT 'urn:svsys:export:user')
SELECT
u.userId
,u.identityNumber
,u.firstName
,u.lastName
,(SELECT
ur.userRole
FROM #testis ur
WHERE ur.userId = u.id
FOR XML PATH (''), ROOT ('userRoles'), TYPE, ELEMENTS)
FROM dbo.TestUser u
FOR XML PATH ('user'), ROOT ('users')
当以用户 UserForMaskedData 身份执行存储过程时,我得到了我想要的结果:
<users xmlns="urn:svsys:export:user">
<user>
<userId>200</userId>
<identityNumber>19520101</identityNumber>
<firstName>Paxxxxxxxxx</firstName>
<lastName>Smxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Roxxxxxxxxx</userRole>
</userRoles>
</user>
<user>
<userId>300</userId>
<identityNumber>19500101</identityNumber>
<firstName>Trxxxxxxxxx</firstName>
<lastName>Boxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Baxxxxxxxxx</userRole>
</userRoles>
</user>
<user>
<userId>400</userId>
<identityNumber>19460101</identityNumber>
<firstName>Mixxxxxxxxx</firstName>
<lastName>Roxxxxxxxxx</lastName>
<userRoles xmlns="urn:svsys:export:user">
<userRole>Guxxxxxxxxx</userRole>
<userRole>Pixxxxxxxxx</userRole>
</userRoles>
</user>
</users>