向 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
如何在不属于sysadmin
或SQLAgentOperatorRole
的情况下运行该工作。另外,不是 Job 的所有者,同时是 SQLAgentUserRole
的成员
OP 明确表示不希望用户能够运行其他作业。这不是 我的 要求,而是 OP 的要求;但这不符合。以上是关于向 SQL Server 用户授予执行权限以仅运行特定作业的主要内容,如果未能解决你的问题,请参考以下文章