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