SQL Server 权限检查何时完成?

jya*_*yao 2 sql-server permissions

当用户要执行一个复杂的存储过程时,其中有相当多的表/视图甚至另一个存储过程。

我的问题是:

SQL server 在生成执行计划之前,会检查用户的权限吗?

否则,如果用户首先没有EXEC此存储过程的权限,则生成执行计划本身就是一种开销成本。

如果是,在我看来,SQL Server 引擎没有任何可消耗的东西,即没有安全标识符(如存储过程本身、存储过程中的表等),SQL Server 引擎可以使用它来检查用户权限. 至少在解析完成之前,不会生成所有这些安全标识符。

那么从执行存储过程的生命周期角度来看,SQL Server 权限检查何时开始?

Dav*_*oft 5

此处详细说明了这一点:

https://docs.microsoft.com/en-us/sql/relational-databases/security/permissions-database-engine

但基本的答案是存储过程已经缓存并重用了查询计划,并且当从存储过程访问存储过程所有者拥有的对象时不需要进行权限检查。如果过程和要访问的对象之间存在有效的所有权链,则在启动存储过程之前只检查 EXECUTE 权限。其他权限检查将被跳过。

您能否提出一个关于在提交后如何处理查询(或 SP)的步骤列表?

这里要记住的主要事情是批处理中的所有查询在其中任何一个开始执行之前都会被解析和编译。在执行期间检查权限。甚至可以在查询中引用一个表,从而实际上从未检查该表的权限。

如果您观看这样的 XE 会话:

CREATE EVENT SESSION [compiles] ON SERVER 
ADD EVENT sqlserver.query_post_compilation_showplan(
    ACTION(sqlserver.sql_text)
    WHERE ([sqlserver].[client_app_name]=N'Microsoft SQL Server Management Studio - Query'))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=1 SECONDS)
Run Code Online (Sandbox Code Playgroud)

并做类似的事情

use tempdb

create table t(id int)
create table w(id int)

create user fred without login

grant select on w to fred
Run Code Online (Sandbox Code Playgroud)

然后:

dbcc freeproccache

go
execute as user='fred'

go
select * from w
select * from t 
go

select 1 
where 1 = case when 1=1 then 1 else (select count(*) from t) end

revert
Run Code Online (Sandbox Code Playgroud)

您将看到第一批中的查询计划都已编译,然后第一个查询运行,然后第二个查询失败。第三个查询在没有权限检查的情况下成功。