Как использовать EXECUTE AS в процедуре, не предоставляя пользователю явных разрешений IMPERSONATE?

У меня есть хранимая процедура в SQL Server 2019. Она усекает промежуточную таблицу, а затем вставляет данные. Я предоставил User1EXECUTE разрешения для этой хранимой процедуры usp_insert_data.

Однако когда я выполняю хранимую процедуру, она терпит неудачу из-за TRUNCATE. Если я удалю TRUNCATE, все будет работать нормально. Насколько я понимаю, TRUNCATE могут создавать только пользователи с определенными привилегиями, которые я не хочу предоставлять User1.

Я создал другого пользователя PowerUser, которому дал ALTER разрешения на доступ к таблице tbl_data, а затем включил следующий код в свою хранимую процедуру:

EXECUTE AS USER = N'PowerUser';

TRUNCATE TABLE [dbo].[tbl_data];

REVERT;

Моя хранимая процедура теперь выглядит так:

ALTER PROCEDURE [dbo].[usp_insert_data]
    @id bigint,
    @utc datetime,
    @latitude decimal(19,15),
    @longitude decimal(19,15)
AS
    SET NOCOUNT ON;
BEGIN
    EXECUTE AS USER = N'PowerUser';

    TRUNCATE TABLE [dbo].[tbl_data];

    REVERT;

    INSERT INTO [tbl_data] (plot_id, utc, gmt,
                            latitude, longitude)
    VALUES (@plot_id, @utc,
            @utc AT TIME ZONE 'UTC' AT TIME ZONE 'GMT Standard Time',
            @latitude, @longitude)
END;

Но я все еще получаю следующую ошибку:

Сообщение 1088, уровень 16, состояние 7, процедура dbo.usp_insert_data, строка 7 [строка запуска пакета 2]
Невозможно найти объект «tbl_data», поскольку он не существует или у вас нет разрешений.

Чтобы разрешить EXECUTE AS PowerUser User1, мне нужно запустить этот код:

GRANT IMPERSONATE ON USER:: [PowerUser] TO [User1]

что означало бы, что пользователь может выдавать себя за другое лицо по своему желанию или я делаю что-то не так?

Спасибо

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы использовать оператор EXECUTE AS в хранимой процедуре, USER/LOGIN требуется явное разрешение на олицетворение этого USER/LOGIN. Вместо этого вам следует определить EXECUTE AS в предложении WITH процедуры и определить PowerUserUSER в этом предложении. Например:

--Create a sample table
CREATE TABLE dbo.SomeTable (SomeID int IDENTITY CONSTRAINT PK_SomeTable PRIMARY KEY,
                            SomeString varchar(10),
                            SomeDate date,
                            SomeInt int,
                            TheUser sysname DEFAULT USER_NAME());
GO
--Create the sample user and a power user
CREATE USER SomeUser WITHOUT LOGIN;
CREATE USER PowerUser WITHOUT LOGIN;
GO
GRANT ALTER, INSERT ON dbo.SomeTable TO PowerUser; --Give the PowerUser the ability to ALTER and INSERT the sample table
GO
--Create the sample procedure that TRUNCATEs and the INSERTs into the table
CREATE OR ALTER PROC dbo.SomeProc @SomeString varchar(10),
                                  @SomeDate date,
                                  @SomeInt int
WITH EXECUTE AS 'PowerUser' AS --now the proc will execute as the PowerUser                          
BEGIN

    SET NOCOUNT ON;

    TRUNCATE TABLE dbo.SomeTable;

    INSERT INTO dbo.SomeTable (SomeString, SomeDate, SomeInt)
    VALUES(@SomeString, @SomeDate, @SomeInt);
END;
GO
--Give the sample user permission to execute the proc
GRANT EXECUTE ON dbo.SomeProc TO SomeUser;
GO
--Impersonate our sample user
EXECUTE AS USER = N'SomeUser';
GO
--Run the proc
EXEC dbo.SomeProc 'abc', '20240621','123';
GO
--Run the proc again (this'll delete the original row) 
EXEC dbo.SomeProc 'def', '20240622','456';
GO
--Back to "us"
REVERT;
GO
--Check the data is the second data set, but will have an ID of 1, not 2.
SELECT *
FROM dbo.SomeTable;

GO
--Clean up
DROP USER SomeUser;
DROP PROC dbo.SomeProc;
DROP TABLE dbo.SomeTable;

Если вы хотите вернуться к вызывающему пользователю в рамках процедуры, вы можете использовать EXECUTE AS CALLER:

CREATE OR ALTER PROC dbo.SomeProc @SomeString varchar(10),
                                  @SomeDate date,
                                  @SomeInt int
WITH EXECUTE AS 'PowerUser' AS --now the proc will execute as the PowerUser                          
BEGIN

    SET NOCOUNT ON;

    TRUNCATE TABLE dbo.SomeTable;

    EXECUTE AS CALLER; --Now we're whoever ran the EXEC

    INSERT INTO dbo.SomeTable (SomeString, SomeDate, SomeInt)
    VALUES(@SomeString, @SomeDate, @SomeInt);
    
    REVERT; --Isn't really needed, but to be "safe"
END;

Мне нравится этот тестовый скрипт, он показывает весь принцип. Будет ли «С ВЫПОЛНЕНИЕМ КАК ВЛАДЕЛЬЦА» полезной и безопасной альтернативой? Или мы всегда должны создавать пользователя «PowerUser» с разрешениями, ограниченными конкретным конкретным использованием?

Der U 26.06.2024 09:09

Сейчас я не могу проверить, но помню, что OWNER не предоставил необходимые разрешения TRUNCATE здесь, @DerU .

Thom A 26.06.2024 09:24

Если владелец sp также является владельцем базы данных, то почти наверняка у него есть разрешение ALTER (необходимое для TRUNCATE) на таблицу (в той же базе данных). Если это не владелец базы данных, нам нужно убедиться, что пользователь, владеющий sp, также имеет разрешения ALTER для таблицы. Лучше всего создать отдельного пользователя («PowerUser») со всеми конкретными разрешениями и только с ними.

Der U 27.06.2024 00:23

Другие вопросы по теме