我正在尝试允许模拟的存储过程使用为SP签名的证书设置的权限访问其他数据库中的视图。
设置(简化)
数据库A
- 表1
- ViewForeign:SELECT*FROM DatabaseB.ExposedView
- ViewResult:SELECT*FROM Table1 AS t1 INNER JOIN ViewForeign VF ON t1.SomeKey=VF.SomeKey
- 存储过程GetData->SELECT*FROM ViewResult
数据库B:
- 表格
- 查看ExposedView->选择*FROM SomeTables
My DatabaseA有一些特权用户,他们可以做很多事情,让我们称其中一个为"超级用户"。对于他们来说,DatabaseB中也存在一个用户,所以他们访问DatabaseB中公开的视图没有问题。现在,我已经创建了一个非常有限的用户,我们称之为"StupidUser",他只对DatabaseA.GetData SP具有执行权限。为了避免同时授予SELECT或其他权限,我创建了SPWITH EXECUTE AS 'SuperUser'
在查询访问其他数据库之前,这一切都很好:The server principal "SuperUser" is not able to access the database "DatabaseB" under the current security context.
Erland Sommarskog的博客研究了一下我的圣经,揭示了所有权链是罪魁祸首。因此,我尝试在DatabaseA:中使用证书对SP进行签名
CREATE CERTIFICATE AccessResourcesReadOnly
ENCRYPTION BY PASSWORD = 'veryComplicatedPassword'
WITH SUBJECT = 'AccessResourcesReadOnly', EXPIRY_DATE = '2029-01-31T00:00:00'
ADD SIGNATURE TO [dbo].[GetData] BY CERTIFICATE AccessResourcesReadOnly WITH PASSWORD = 'veryComplicatedPassword'
卡在这里:
现在,我正在尝试为该证书添加一个用户,该用户在DatabaseB中对公开的视图具有连接/选择权限。运行
CREATE USER AccessResourcesFromCertificateReadOnly
FROM CERTIFICATE AccessResourcesReadOnly;
在"数据库B"中导致
Cannot find the certificate 'AccessResourcesReadOnly', because it does not exist or you do not have permission.
相反,在"master"中创建证书没有帮助;我已经尝试过了,但在数据库A中找不到ADD SIGNATURE TO dbo.GetData
的证书名称,在数据库B中也找不到CREATE USER FROM CERTIFICATE
的证书名称。我做错了什么?如何以允许SP访问DatabaseB.ExposedView
的方式对DatabaseA.GetData
进行签名?
你应该将export certificate
和import
放入DatabaseB
中,你的证书应该存在于这两个数据库中,现在你只有DatabaseA
中的证书,这就是为什么你得到
找不到证书"AccessResourcesReadOnly",因为它不存在
引用博客的完整解决方案是:
- 在目标数据库中创建证书,即PlaySign-in这个例子
- 根据证书创建用户
- 授予用户所需的权限
- 导出证书
- 将证书导入原始数据库
- 签署有问题的程序
- 可选:删除私钥
p.S.在您的情况下,简单的cross database chaining
也会起作用。