Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве приведен пример, в котором рассматриваются основные понятия безопасности SQL Server, включая цепочки владения и переключение контекста пользователя.
Замечание
Чтобы запустить код в этом руководстве, необходимо настроить как безопасность смешанного режима, так и базу данных AdventureWorks2012 . Дополнительные сведения о безопасности смешанного режима см. в разделе "Выбор режима проверки подлинности".
Сценарий
В этом сценарии двум пользователям требуется доступ к данным заказа на покупку, хранящимся в базе данных AdventureWorks2012 . Ниже приведены требования.
Первая учетная запись (TestManagerUser) должна иметь возможность просматривать все сведения в каждом заказе на покупку.
Вторая учетная запись (TestEmployeeUser) должна иметь возможность видеть номер заказа на покупку, дату заказа, дату доставки, номера идентификаторов продукта, а также заказанные и полученные элементы, которые организованы по номеру заказа на покупку, для элементов с полученными частичными поставками.
Все остальные учетные записи должны хранить текущие разрешения.
Для выполнения требований этого сценария пример разбивается на четыре части, демонстрирующие основные понятия цепочек владения и переключения контекста:
Настройка среды.
Создание хранимой процедуры для доступа к данным по заказу на покупку.
Доступ к данным через хранимую процедуру.
Сброс среды.
Каждый блок кода в этом примере описывается в строке. Чтобы скопировать полный пример, ознакомьтесь с полным примером в конце этого руководства.
1. Настройка среды
Используйте SQL Server Management Studio и следующий код, чтобы открыть базу данных AdventureWorks2012, и используйте инструкцию CURRENT_USER Transact-SQL, чтобы проверить, отображается ли пользователь dbo в контексте.
USE AdventureWorks2012;
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
Дополнительные сведения об инструкции CURRENT_USER см. в разделе CURRENT_USER (Transact-SQL).
Используйте этот код в качестве пользователя dbo, чтобы создать двух пользователей на сервере и в базе данных AdventureWorks2012 .
CREATE LOGIN TestManagerUser
WITH PASSWORD = '340$Uuxwp7Mcxo7Khx';
GO
CREATE USER TestManagerUser
FOR LOGIN TestManagerUser
WITH DEFAULT_SCHEMA = Purchasing;
GO
CREATE LOGIN TestEmployeeUser
WITH PASSWORD = '340$Uuxwp7Mcxo7Khy';
GO
CREATE USER TestEmployeeUser
FOR LOGIN TestEmployeeUser;
GO
Дополнительные сведения об инструкции CREATE USER см. в статье CREATE USER (Transact-SQL). Дополнительные сведения об инструкции CREATE LOGIN см. в статье CREATE LOGIN (Transact-SQL).
Используйте следующий код, чтобы изменить владельца схемы Purchasing на учетную запись TestManagerUser. Это позволяет учетной записи использовать все доступ к инструкции языка обработки данных (DML) (например SELECT , и INSERT разрешения) для объектов, содержащихся в нем.
TestManagerUser также предоставляется возможность создавать хранимые процедуры.
/* Change owner of the Purchasing Schema to TestManagerUser */
ALTER AUTHORIZATION
ON SCHEMA::Purchasing
TO TestManagerUser;
GO
GRANT CREATE PROCEDURE
TO TestManagerUser
WITH GRANT OPTION;
GO
Дополнительные сведения об инструкции GRANT см. в разделе GRANT (Transact-SQL). Дополнительные сведения о хранимых процедурах см. в разделе Хранимые процедуры (ядро СУБД). Для получения плаката, содержащего все разрешения ядра СУБД, см. https://github.com/microsoft/sql-server-samples/blob/master/samples/features/security/permissions-posters/Microsoft_SQL_Server_2017_and_Azure_SQL_Database_permissions_infographic.pdf.
2. Создание хранимой процедуры для доступа к данным
Чтобы переключить контекст в базе данных, используйте инструкцию EXECUTE AS. Для EXECUTE AS требуются права IMPERSONATE.
Используйте оператор EXECUTE AS в следующем коде, чтобы изменить контекст на TestManagerUser и создать хранимую процедуру, показывающую только данные, требуемые для TestEmployeeUser. Для удовлетворения требований хранимая процедура принимает одну переменную для номера заказа на покупку и не отображает финансовую информацию, а предложение WHERE ограничивает результаты частичными отгрузками.
EXECUTE AS LOGIN = 'TestManagerUser'
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
/* Note: The user that calls the EXECUTE AS statement must have IMPERSONATE permissions on the target principal */
CREATE PROCEDURE usp_ShowWaitingItems @ProductID int
AS
BEGIN
SELECT a.PurchaseOrderID, a.OrderDate, a.ShipDate
, b.ProductID, b.OrderQty, b.ReceivedQty
FROM Purchasing.PurchaseOrderHeader a
INNER JOIN Purchasing.PurchaseOrderDetail b
ON a.PurchaseOrderID = b.PurchaseOrderID
WHERE b.OrderQty > b.ReceivedQty
AND @ProductID = b.ProductID
ORDER BY b.ProductID ASC
END
GO
TestEmployeeUser В настоящее время нет доступа к объектам базы данных. Следующий код (по-прежнему в TestManagerUser контексте) предоставляет учетной записи пользователя возможность запрашивать сведения базовой таблицы с помощью хранимой процедуры.
GRANT EXECUTE
ON OBJECT::Purchasing.usp_ShowWaitingItems
TO TestEmployeeUser;
GO
Хранимая процедура является частью схемы Purchasing, даже если схема не была явно указана, потому что TestManagerUser по умолчанию назначается схеме Purchasing. Сведения о системном каталоге можно использовать для поиска объектов, как показано в следующем коде.
SELECT a.name AS 'Schema'
, b.name AS 'Object Name'
, b.type AS 'Object Type'
FROM sys.schemas a
INNER JOIN sys.objects b
ON a.schema_id = b.schema_id
WHERE b.name = 'usp_ShowWaitingItems';
GO
После выполнения этого раздела примера, код переключает контекст обратно к объекту dbo с помощью инструкции REVERT.
REVERT;
GO
Дополнительные сведения об инструкции REVERT см. в разделе REVERT (Transact-SQL).
3. Доступ к данным с помощью хранимой процедуры
TestEmployeeUser не имеет разрешений на объекты базы данных AdventureWorks2012 , отличные от имени входа и прав, назначенных роли общедоступной базы данных. Следующий код возвращает ошибку при TestEmployeeUser попытке доступа к базовым таблицам.
EXECUTE AS LOGIN = 'TestEmployeeUser'
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
/* This won't work */
SELECT *
FROM Purchasing.PurchaseOrderHeader;
GO
SELECT *
FROM Purchasing.PurchaseOrderDetail;
GO
Так как объекты, на которые ссылается хранимая процедура, созданная в последнем разделе, принадлежат TestManagerUser по причине Purchasing владения схемой, TestEmployeeUser могут получить доступ к базовым таблицам через хранимую процедуру. Следующий код, по-прежнему использующий TestEmployeeUser контекст, передает заказ на покупку 952 в качестве параметра.
EXEC Purchasing.usp_ShowWaitingItems 952
GO
4. Сброс среды
Следующий код использует команду REVERT для возвращения контекста текущей учетной записи к dbo, а затем сбрасывает окружение.
REVERT;
GO
ALTER AUTHORIZATION
ON SCHEMA::Purchasing TO dbo;
GO
DROP PROCEDURE Purchasing.usp_ShowWaitingItems;
GO
DROP USER TestEmployeeUser;
GO
DROP USER TestManagerUser;
GO
DROP LOGIN TestEmployeeUser;
GO
DROP LOGIN TestManagerUser;
GO
Полный пример
В этом разделе показан полный пример кода.
Замечание
Этот код не включает в себя две ожидаемые ошибки, демонстрирующие неспособность TestEmployeeUser выбирать из базовых таблиц.
/*
Script: UserContextTutorial.sql
Author: Microsoft
Last Updated: Books Online
Conditions: Execute as DBO or sysadmin in the AdventureWorks database
Section 1: Configure the Environment
*/
USE AdventureWorks2012;
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
/* Create server and database users */
CREATE LOGIN TestManagerUser
WITH PASSWORD = '340$Uuxwp7Mcxo7Khx';
GO
CREATE USER TestManagerUser
FOR LOGIN TestManagerUser
WITH DEFAULT_SCHEMA = Purchasing;
GO
CREATE LOGIN TestEmployeeUser
WITH PASSWORD = '340$Uuxwp7Mcxo7Khy';
GO
CREATE USER TestEmployeeUser
FOR LOGIN TestEmployeeUser;
GO
/* Change owner of the Purchasing Schema to TestManagerUser */
ALTER AUTHORIZATION
ON SCHEMA::Purchasing
TO TestManagerUser;
GO
GRANT CREATE PROCEDURE
TO TestManagerUser
WITH GRANT OPTION;
GO
/*
Section 2: Switch Context and Create Objects
*/
EXECUTE AS LOGIN = 'TestManagerUser';
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
/* Note: The user that calls the EXECUTE AS statement must have IMPERSONATE permissions on the target principal */
CREATE PROCEDURE usp_ShowWaitingItems @ProductID int
AS
BEGIN
SELECT a.PurchaseOrderID, a.OrderDate, a.ShipDate
, b.ProductID, b.OrderQty, b.ReceivedQty
FROM Purchasing.PurchaseOrderHeader AS a
INNER JOIN Purchasing.PurchaseOrderDetail AS b
ON a.PurchaseOrderID = b.PurchaseOrderID
WHERE b.OrderQty > b.ReceivedQty
AND @ProductID = b.ProductID
ORDER BY b.ProductID ASC
END;
GO
/* Give the employee the ability to run the procedure */
GRANT EXECUTE
ON OBJECT::Purchasing.usp_ShowWaitingItems
TO TestEmployeeUser;
GO
/* Notice that the stored procedure is located in the Purchasing
schema. This also demonstrates system catalogs */
SELECT a.name AS 'Schema'
, b.name AS 'Object Name'
, b.type AS 'Object Type'
FROM sys.schemas AS a
INNER JOIN sys.objects AS b
ON a.schema_id = b.schema_id
WHERE b.name = 'usp_ShowWaitingItems';
GO
/* Go back to being the dbo user */
REVERT;
GO
/*
Section 3: Switch Context and Observe Security
*/
EXECUTE AS LOGIN = 'TestEmployeeUser';
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
EXEC Purchasing.usp_ShowWaitingItems 952;
GO
/*
Section 4: Clean Up Example
*/
REVERT;
GO
ALTER AUTHORIZATION
ON SCHEMA::Purchasing TO dbo;
GO
DROP PROCEDURE Purchasing.usp_ShowWaitingItems;
GO
DROP USER TestEmployeeUser;
GO
DROP USER TestManagerUser;
GO
DROP LOGIN TestEmployeeUser;
GO
DROP LOGIN TestManagerUser;
GO
См. также
Центр безопасности для ядра СУБД SQL Server и Базы данных Azure SQL