通常,我有普通用户连接到我的 SQL Server 数据库并在名为 的架构中执行存储过程myschema
。
如果这些用户尝试从数据库的表中获取数据,他们看不到任何表,但他们可以通过myschema
.
现在我正在查询sys.dm_exec_sessions
并且sys.dm_exec_connections
希望采用相同的方法,但是不行,我必须VIEW SERVER STATE
向调用该过程的用户授予权限myschema.GetUserSessions
!
毕竟,我希望用户只能访问 和 的某些字段sys.dm_exec_sessions
,sys.dm_exec_connections
而不是整个视图,并且只能通过这个存储过程,但不能直接访问。
目前我正在使用一种解决方法,即检查权限并返回具有正确数据类型的空结果集:
CREATE PROCEDURE myschema.GetUserSessions
AS
/* To be able to run this procedure an user should have VIEW SERVER STATE permission:
USE master;
GRANT VIEW SERVER STATE TO [HOST\Username];
*/
IF EXISTS(SELECT permission_name FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name = 'VIEW SERVER STATE') BEGIN
SELECT
ses.login_name,
ses.[host_name],
con.client_net_address,
ses.[program_name],
ses.login_time,
ses.last_request_start_time,
ses.last_request_end_time,
con.net_transport,
con.encrypt_option
FROM
sys.dm_exec_sessions ses
inner join sys.dm_exec_connections con on con.session_id = ses.session_id
WHERE
is_user_process = 1
END
ELSE BEGIN
SELECT
login_name = CAST('' AS NVARCHAR),
[host_name] = CAST(NULL AS NVARCHAR),
client_net_address = CAST(NULL AS VARCHAR),
[program_name] = CAST(NULL AS NVARCHAR),
login_time = CAST(0 AS DATETIME),
last_request_start_time = CAST(0 AS DATETIME),
last_request_end_time = CAST(NULL AS DATETIME),
net_transport = CAST('' AS NVARCHAR),
encrypt_option = CAST('' AS NVARCHAR)
WHERE
1 = 0
END
老实说,我不喜欢既不VIEW SERVER STATE
向用户授予权限也不不时将数据保存到某个中间表的想法。
您可以使用模块签名来完成此操作,因为您已经为此最终结果创建了存储过程。根据您的用例,这可能有很多模块。
如果您无论如何都要向所有人展示所有结果,我不确定是否需要进行模块签名以及是否厌恶查看服务器状态,但这也不是我的环境。你有多种选择,选择一个或多个,但都会受到产品“限制”的限制。如果这些都不适合你,那么要么不要让人们看到,要么做出让步。