【问题标题】:Allowing a stored procedure to select from a system table using a certificate in SQL Server 2012允许存储过程使用 SQL Server 2012 中的证书从系统表中进行选择
【发布时间】:2012-01-11 14:41:05
【问题描述】:

我目前在尝试运行尝试从系统表中进行选择的存储过程时遇到与权限相关的问题。基本上,我试图通过直接从 sys.dm_tran_current_transaction 表中获取我需要的数据来解决 SQL Server 2012 中 sp_bindtoken 系统存储过程的弃用问题。

我发现的一个解决方案是:

  • 创建证书
  • 从证书创建用户/登录
  • 授予用户查看服务器状态权限
  • 使用证书对存储过程进行签名
  • 执行存储过程,该过程在刚刚创建的用户的上下文中运行

这种方法似乎在 SQL Server 2008 R2 中运行良好。然而在 SQL Server 2012 中,即使脚本看起来运行正确,但在运行时存储过程会在尝试从上述系统表中进行选择时失败并出现权限错误。

我目前的脚本有点像这样:

USE OurDatabase
GO

CREATE CERTIFICATE OurDatabaseProcCert
FROM FILE = 'C:\Path\To\OurDatabaseProcCert.cer'
WITH PRIVATE KEY (
FILE = 'C:\Path\To\OurDatabaseProcCert.pvk',
ENCRYPTION BY PASSWORD = '$0m3$tr0ngp@$$w0rd',
DECRYPTION BY PASSWORD = '$0m3$tr0ngp@$$w0rd');
GO

USE master
GO

CREATE CERTIFICATE OurDatabaseProcCert
    FROM FILE = 'C:\Path\To\OurDatabaseProcCert.cer'
WITH PRIVATE KEY (
    FILE = 'C:\Path\To\OurDatabaseProcCert.pvk',
    ENCRYPTION BY PASSWORD = '$0m3$tr0ngp@$$w0rd',
    DECRYPTION BY PASSWORD = '$0m3$tr0ngp@$$w0rd');
GO

CREATE LOGIN OurDatabaseServerLogin
    FROM CERTIFICATE OurDatabaseProcCert
GO

CREATE USER OurDatabaseServerLogin

REVOKE CONNECT SQL FROM OurDatabaseServerLogin
GO 

GRANT AUTHENTICATE SERVER TO OurDatabaseServerLogin
GO

GRANT VIEW SERVER STATE TO OurDatabaseServerLogin
GO

USE OurDatabase
GO

ADD SIGNATURE TO dbo.bsp_getTransactionID BY CERTIFICATE OurDatabaseProcCert WITH PASSWORD = '$0m3$tr0ngp@$$w0rd'

这是创建我要签名/执行的存储过程的代码:

CREATE Procedure bsp_getTransactionID
(
    @TransactionID  VARCHAR(255) OUTPUT
)
AS      
BEGIN
    IF @@TRANCOUNT > 0  
    BEGIN
        SELECT SYSTEM_USER
        SELECT @TransactionID = sys.dm_tran_current_transaction.transaction_id FROM sys.dm_tran_current_transaction
    END 
 RETURN 0
END
GO

以前有没有人遇到过这类问题?

【问题讨论】:

    标签: sql sql-server stored-procedures sql-server-2012 database-permissions


    【解决方案1】:

    虽然我不明白为什么它会在 2012 年做出不同的反应,但我想知道您是否可以通过使用 CREATE PROCEDURE 中的 EXECUTE AS <certificate_logon> 子句来解决它。

    理论上这应该等同于您的解决方案,因为默认为EXECUTE AS owner,但它的反应可能略有不同???我认为值得一试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      相关资源
      最近更新 更多