В настоящее время у меня возникают проблемы, связанные с разрешениями при попытке запустить хранимую процедуру, которая пытается выбрать из системной таблицы. По сути, я пытаюсь обойти устаревшую системную хранимую процедуру 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
Кто-нибудь сталкивался с такой проблемой раньше?