向 SQL Server 用户授予执行权限以仅运行特定作业

Posted

技术标签:

【中文标题】向 SQL Server 用户授予执行权限以仅运行特定作业【英文标题】:Grant execute permission to an SQL Server user to run a specific job only 【发布时间】:2019-08-23 09:42:47 【问题描述】:

我有创建可由特定 SQL 用户运行的 SQL Server 代理作业的请求。

如果不授予用户对 sp_start_job 存储过程的执行权限,这意味着他也可以运行所有其他被禁止的作业,如何做到这一点?

【问题讨论】:

通过使用EXECUTE AS OWNER 创建一个仅启动该作业的过程,并授予用户对此的权限。 (如果出于某种原因EXECUTE AS OWNER 被认为风险太大或者您有跨数据库问题,请阅读this 了解有关如何“整齐”地使用证书做事的更多详细信息。) 遗憾的是,由于安全问题,以所有者身份执行将无法工作。谢谢你的链接,我会读的。 您能否更具体地说明您的声明“由于安全问题”?特别是什么问题? 使用 Jeroen 提到的证书。这是最好的方法,也是最复杂的方法。 【参考方案1】:

如果不授予用户对 sp_start_job 存储过程的执行权限,这意味着他也可以运行所有其他被禁止的作业,如何做到这一点?

通常,分配给SQLAgentUserRole的用户(msdb中的数据库角色)只能访问该用户作为所有者的SQL作业,

在您的情况下,您可以应用以下简单步骤

以下步骤创建一个可由login 执行的作业,而同样的login 无法运行 SQL 代理中可用的其他作业:

    在创建作业时(查看示例参考),通过将所需的 login 名称包含在参数 @owner_login_name 中,将其包含为作业所有者 确保映射为作业所有者的Login(在步骤 1 中)不是Sysadmin 固定服务器角色和SQLAgentOperatorRole msdb 数据库角色的一部分,而只是SQLAgentUserRole 角色的一部分,您可以通过以下方式执行此操作脚本(将 Loginname 替换为您自己的)
ALTER SERVER ROLE SYSADMIN DROP MEMBER LoginName;

USE MSDB;

CREATE USER LoginName FOR LOGIN LoginName;

ALTER ROLE SQLAGENTUSERROLE ADD MEMBER LoginName;

ALTER ROLE SQLAgentOperatorRole drop MEMBER LoginName;

职位创建示例参考

该脚本创建一个作业并通过sqlcmd 逐步执行T-SQL 命令,运行此作业的用户不需要数据库中特定对象的权限。

在运行以下创建作业的脚本之前,您需要更改@command 参数。或者您可以稍后(在创建作业之后)通过 SSMS - SQL 代理 -> 作业属性

更改它

注意:SQL Agent Service 必须由 windows/domain 用户帐户运行,并且服务帐户用户需要对对象的权限(过程)

USE [msdb]
GO

BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0

IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'Cmd Test With Service Account', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=0, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'No description available.', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [Test]    Script Date: 8/27/2019 5:30:58 PM ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Cmd Test With Service Account', 
        @step_id=1, 
        @cmdexec_success_code=0, 
        @on_success_action=1, 
        @on_success_step_id=0, 
        @on_fail_action=2, 
        @on_fail_step_id=0, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, @subsystem=N'CmdExec', 
        @command=N'"C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\SQLCMD.EXE" -S Localhost,1534 -Q "exec YourDatabase.dbo.YourProcedure"', 
        @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO

【讨论】:

这将如何阻止用户开始其他工作? @Larnu,对不起,我把问题弄错了,错过了完整的答案。但是,编辑了我现在符合该问题的答案。感谢您的通知! 这不会阻止用户开始其他个工作。 @Larnu,您能否解释一下login/user 如何在不属于sysadminSQLAgentOperatorRole 的情况下运行该工作。另外,不是 Job 的所有者,同时是 SQLAgentUserRole 的成员 OP 明确表示不希望用户能够运行其他作业。这不是 我的 要求,而是 OP 的要求;但这不符合。

以上是关于向 SQL Server 用户授予执行权限以仅运行特定作业的主要内容,如果未能解决你的问题,请参考以下文章

授予用户权限以仅查看 MySQL 视图而不查看其他内容

sql 权限授予 sql server

SQL Server中授予用户查看对象定义的权限

SQL Server中授予用户查看对象定义的权限

如何授予用户对 SQL Server 中数据库的读取权限?

sql SQL语句向用户授予SQL对象的权限