假设在数据库中创建了一个证书
create certificate certName
with subject = 'subj';
GO
以及映射到此证书的用户
create user userName
from certificate certName;
GO
试图直接冒充该用户
execute as user = 'userName';
GO
execute as
或在模块的子句中指定用户
create procedure procName
with execute as 'userName'
as
set nocount on;
GO
返回错误
消息 15517,级别 16,状态 1 ...
无法作为数据库主体执行,因为主体“userName”不存在,无法模拟此类主体,或者您没有权限。
但是,我无法找到文档(此处和此处)中提到的此限制,其中唯一相关的声明似乎是
user_name 必须存在于当前数据库中,并且必须是单例帐户。user_name 不能是组、角色、证书、密钥或内置帐户,例如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
是否可以模拟映射到证书的用户(或登录名)?
不能模拟从证书和非对称密钥创建的登录名和用户。它们只是一组权限的代理,这些权限将添加到使用相同证书或非对称密钥签名的任何模块中。
此外,冒充这些登录名和用户并没有多大意义,因为:
EXECUTE AS
这是通过在对已签名模块进行任何更改时删除签名以及使用模块文本(包括语句的可选子句CREATE
)来创建签名的事实来处理的。如果文本更改,则签名将不匹配。最后,使用从非对称密钥和证书创建的登录名和/或用户取代了对模拟的需求。
不过,如果要寻找更官方的指标,CREATE USER的 MSDN 页面指出:
但是,无法登录/身份验证并不意味着“无法模拟”,因为没有登录的用户在该列表中,并且您可以执行
EXECUTE AS USER='{user_without_login}';
.CREATE LOGIN的 MSDN 页面指出:
虽然第二句重复了
CREATE USER
文档所说的内容,但第一句更加具体:它们仅用于代码签名。最后,您在文档中找到的关于EXECUTE AS和EXECUTE AS 子句的限制声明是正确的,即使它们的措辞令人困惑。他们说(加粗强调):
该引用取自
EXECUTE AS
文档,并且EXECUTE AS Clause
问题中引用了文档(几乎相同的措辞)。虽然这两个页面都使用术语“证书”和“密钥”,但它们实际上分别表示“基于证书的登录/用户”和“基于非对称密钥的登录/用户”。我假设这是基于这样一个事实,即给定的主体类型列表都可以在sys.server_principals
(对于登录)和sys.database_principals
(对于用户)中找到,并且证书和非对称密钥都不会在这些系统目录视图中列出。