sql-server - 如何授予用户角色具有授予选项的权限?
问题描述
我正在直接在 SQL Server 2017 上为我公司软件的新版本设置安全登录系统。我正在尝试撤销用户帐户对任何数据库的 CONNECT 权限,直到用户使用设置的用户名登录到初始身份验证数据库/password,并使用登录过程在特定数据库上启用他们的帐户,然后客户端将断开与初始数据库的连接并使用他们的个人帐户重新连接,连接到他们的目标数据库。
在初始数据库中创建了一个证书,用于对调用如下所示的过程进行签名。下面显示的过程没有任何证书签名。创建的证书被复制到目标数据库,并用于创建一个用户,然后将该用户添加到一个组中Certified
,该用户有权执行下面显示的过程,并且CONNECT WITH GRANT OPTION
对数据库具有权限。当下面的过程被执行时,grant/revoke 语句失败,说授予者没有必要的权限(或者找不到用户/角色,取决于我是否尝试添加 AS 子句)
连接权限的授予/撤销是通过目标数据库中存储过程中的动态 SQL 完成的(我们软件中的每个数据库都有一个相同的过程来完成这项工作)。如果我以 sysadmin 固定角色的成员身份运行代码,则它可以工作,但当我使用我设置的身份验证帐户运行它时,它就不行了。目标数据库中的ModifyUser
过程(但是,每当我运行该过程时,该语句都会失败。Certified
CONNECT WITH GRANT OPTION
我尝试了 3 个版本,更改了 AS 子句的内容:
- 作为证书用户,他是数据库角色的一部分,
uCompCompID
- 作为数据库角色,证书用户是其中的一部分,
Certified
- SQL Server 文档似乎不清楚在尝试授予角色具有授予选项的权限时应该使用哪些
- 不带AS子句,以授予运行动态SQL的用户权限
- 这似乎以身份验证用户身份运行查询,而不是作为具有授予选项的角色成员的证书用户
CONNECT
- 这似乎以身份验证用户身份运行查询,而不是作为具有授予选项的角色成员的证书用户
ModifyUser
过程很短,所以我将在下面包括整个过程。此过程存储在与我要授予/撤销CONNECT
权限的用户相同的数据库中,但调用由与在同一数据库中创建的用户匹配的证书签名的不同数据库。
这是版本 3,其中没有 AS 子句。
PROCEDURE [Authorization].[ModifyUser]
@user nvarchar(128),
@status bit
AS
BEGIN
SET NOCOUNT ON
IF @user IS NULL
THROW 50002, 'Invalid argument: @user', 0
IF LTRIM(RTRIM(@user)) = ''
THROW 50002, 'Invalid argument: @user', 1
IF @status IS NULL
THROW 50002, 'Invalid argument: @status', 0
DECLARE @statement nvarchar(200)
IF @status = 1
SET @statement = 'GRANT CONNECT TO ' + @user
ELSE
SET @statement = 'REVOKE CONNECT TO ' + @user
EXEC (@statement)
END
预期的结果是CONNECT
目标用户的权限发生了变化,但接收到的结果始终是错误的。确切的错误取决于使用的版本:
- 消息 15151,级别 16,状态 1,行 2 找不到用户“uCompCompID”,因为它不存在或您没有权限。
- 消息 15151,级别 16,状态 1,行 2 找不到用户“已认证”,因为它不存在或您没有权限。
- Msg 4613,Level 16,State 1,Line 2 Grantor 没有 GRANT 权限。
如果我直接授予证书用户权限,这不是问题。但是,我想将权限保留在一个角色中,这样当我在修改该系统所涉及的程序之一后不可避免地需要重新创建证书时,我只需要担心将新证书用户添加到适当的组,而不是每次进行需要重新签署任何证书的更改时都需要向重新创建的用户授予权限。
解决方案
首先,您应该更新您的问题,因为不清楚您创建了哪些数据库cerificate
以及签署了哪些程序,哪些不是:
目标数据库中的过程 (ModifyUser) 是从初始数据库中的另一个过程调用的,该过程使用证书签名,目标数据库中的同一证书中存在一个用户,该用户是已获得认证的角色的成员。授予 CONNECT WITH GRANT OPTION
由此看来,只有初始数据库中的过程是用 a 签名的
certificate
,但内部过程(在目标数据库中)不是,在这种情况下,只有外部过程具有授予从证书创建的用户的权限,这就是为什么你得到错误 N3
Grantor 没有 GRANT 权限
在其他情况下,您会因为使用execute as
子句而出错(该子句只承认user
,而不承认login
!)。当你使用它时,你的 proc 被沙箱化在database
它创建的过程中,即你不能在另一个数据库中做任何事情,即使你是sysadmin
,服务器也不能使用对应的login
(在其他数据库中搜索对应user
的),除非数据库是trustworthy
并且在另一个数据库中owner
没有。authenticate
推荐阅读
- r - 如何将数据框中的相同观察分组为一组
- rest - 如何设计用于向用户发送电子邮件的restful api
- wordpress - wp_options 表中的 site_url 与设置中的站点 URL 不匹配 > 常规
- php - 重音字符的 PHP 正则表达式
- java - 运行“Java 中的数据结构和算法”一书中的旧 Java 小程序
- react-native - 自定义 React 抽屉导航
- symfony - 如何使用文档中提到的服务来生成 url?
- php - 如何使用我的自定义 foreach 循环数据的 joomla 分页
- javascript - JS 库的 Angular 包装器不加载样式
- c# - 数字范围的正则表达式