Разрешение хранимой процедуры выбирать из системной таблицы с помощью сертификата в SQL Server 2012 - PullRequest
11 голосов
/ 02 декабря 2011

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

Я нашел одно решение:

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

Похоже, что этот подход прекрасно работает в 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

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

1 Ответ

1 голос
/ 23 декабря 2011

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

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

...