Разрешение хранимой процедуры выбирать из системной таблицы с использованием сертификата в SQL Server 2012

В настоящее время у меня возникают проблемы с разрешениями при попытке запустить хранимую процедуру, которая пытается выбрать из системной таблицы. В основном я пытаюсь обойти устаревшую системную хранимую процедуру sp_bindtoken в SQL Server 2012, сразу же захватив нужные мне данные из таблицы sys.dm_tran_current_transaction.

Одно из найденных мной решений:

  • Создать сертификат
  • Создайте пользователя/логин из сертификата
  • Предоставьте пользователю разрешение просмотра VIEW SERVER STATE
  • Войдите в хранимую процедуру с помощью сертификата
  • Выполнение хранимой процедуры, которая выполняется в контексте только что созданного пользователя.

Этот подход, похоже, отлично работает в SQL Server 2008 R2. Однако в SQL Server 2012, несмотря на то, что script работает корректно, во время выполнения хранимая процедура выходит из строя с ошибкой разрешений при попытке выбрать из приведенной выше системной таблицы.

script В настоящее время я немного похож на это:

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 = '[email protected]$$w0rd',
DECRYPTION BY PASSWORD = '[email protected]$$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 = '[email protected]$$w0rd',
    DECRYPTION BY PASSWORD = '[email protected]$$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 = '[email protected]$$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

Кто-нибудь сталкивался с этим типом проблемы раньше?

Ответ 1

Хотя я не понимаю, почему в 2012 году он будет реагировать иначе, я задаюсь вопросом, можете ли вы обойти его, используя предложение EXECUTE AS <certificate_logon> в CREATE PROCEDURE.

В теории это должно быть эквивалентно вашему решению, поскольку по умолчанию это EXECUTE AS owner, но, возможно, он реагирует немного по-другому??? Стоит попробовать, я думаю.