Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Используйте функцию контекста сеанса SQL для реализации безопасности на уровне строк в построителе API данных.
Это важно
Контекст сеанса с безопасностью SQL Server на уровне строк отличается от политик базы данных построителя API данных. Политики базы данных (например, --policy-database "@item.owner eq @claims.user_id") переводятся в предложения WHERE с помощью построителя API данных, а контекст сеанса перенаправляет утверждения в SQL Server, чтобы строковая безопасность SQL обрабатывала фильтрацию.
Предпосылки
- Существующий СЕРВЕР SQL и база данных.
- CLI инструмента построения API данных. Установка интерфейса командной строки
Замечание
Контекст сеанса поддерживается в следующих случаях:
- SQL Server 2016 и более поздние версии
- База данных SQL Azure
- Azure Synapse Analytics (выделенный пул SQL)
- Azure Synapse Analytics (бессерверный пул SQL) не поддерживается
Создание таблицы и данных SQL
Создайте таблицу с вымышленными данными для использования в этом примере.
Подключитесь к базе данных SQL с помощью предпочтительного клиента или средства.
Создайте таблицу с именем
Revenuesс колонкамиid,category,revenueиaccessible_role.DROP TABLE IF EXISTS dbo.Revenues; CREATE TABLE dbo.Revenues( id int PRIMARY KEY, category varchar(max) NOT NULL, revenue int, accessible_role varchar(max) NOT NULL ); GOВставьте четыре примера строк в таблицу
Revenues.INSERT INTO dbo.Revenues VALUES (1, 'Book', 5000, 'Oscar'), (2, 'Comics', 10000, 'Oscar'), (3, 'Journals', 20000, 'Hannah'), (4, 'Series', 40000, 'Hannah') GOВ этом примере
accessible_roleстолбец сохраняет имя роли, которое может получить доступ к строке.
Подсказка
Распространенные варианты использования контекста сеанса:
- Фильтрация на основе ролей (показана здесь) с помощью
roles - Многотенантная изоляция с помощью
tenant_id - Фильтрация для конкретных пользователей с помощью
user_id
Протестируйте данные с помощью простого
SELECT *запроса.SELECT * FROM dbo.RevenuesСоздайте функцию с именем
RevenuesPredicate. Эта функция будет фильтровать результаты на основе текущего контекста сеанса.CREATE FUNCTION dbo.RevenuesPredicate(@accessible_role varchar(max)) RETURNS TABLE WITH SCHEMABINDING AS RETURN SELECT 1 AS fn_securitypredicate_result WHERE @accessible_role = CAST(SESSION_CONTEXT(N'roles') AS varchar(max));Создайте политику безопасности с именем
RevenuesSecurityPolicyс помощью функции.CREATE SECURITY POLICY dbo.RevenuesSecurityPolicy ADD FILTER PREDICATE dbo.RevenuesPredicate(accessible_role) ON dbo.Revenues;
Замечание
Предложение WITH SCHEMABINDING требуется для функций, используемых в политиках безопасности, чтобы изменения базовой схемы не делали предикат недействительным.
(Необязательно) Создание хранимой процедуры
В этом разделе показан простой шаблон "hello world" для использования значений контекста сеанса непосредственно в T-SQL.
Создайте хранимую процедуру, которая считывает значение контекста сеанса
rolesи использует ее для фильтрации результатов.CREATE OR ALTER PROCEDURE dbo.GetRevenuesForCurrentRole AS BEGIN SET NOCOUNT ON; DECLARE @role varchar(max) = CAST(SESSION_CONTEXT(N'roles') AS varchar(max)); SELECT id, category, revenue, accessible_role FROM dbo.Revenues WHERE accessible_role = @role; END GO
Инструмент запуска
Запустите инструмент построения данных (DAB), чтобы создать файл конфигурации и одну сущность.
Создайте новую конфигурацию, установив для
--set-session-contextзначение true.dab init \ --database-type mssql \ --connection-string "<sql-connection-string>" \ --set-session-context true \ --auth.provider SimulatorЕсли контекст сеанса включен для SQL Server, построитель API данных отправляет утверждения пользователей, прошедшие проверку подлинности, в SQL путем вызова
sp_set_session_context(например,roles). Включение контекста сеанса также отключает кэширование ответов для этого источника данных.
Предупреждение
Если set-session-context этот параметр включен, кэширование ответов отключено для источника данных. Для сценариев с высоким трафиком рассмотрите возможность тестирования производительности, индексирования столбца предиката или использования политик базы данных построителя данных API, когда они соответствуют вашим потребностям.
Добавьте новую сущность с именем
revenueдляdbo.Revenuesтаблицы.dab add revenue \ --source "dbo.Revenues" \ --permissions "Authenticated:read"Запустите средство построителя API данных.
dab startЗапрос конечной точки без указания эффективной роли. Обратите внимание, что данные не возвращаются, так как:
- По умолчанию эффективная роль — это
Authenticated. - Нет строк, имеющих
accessible_role = 'Authenticated'. - Политика безопасности фильтрует результаты, если роль не соответствует.
curl http://localhost:5000/api/revenue- По умолчанию эффективная роль — это
Выполните запрос к конечной точке, установив эффективную роль на
Oscar. Обратите внимание, что отфильтрованные результаты включают толькоOscarстроки.curl -H "X-MS-API-ROLE: Oscar" http://localhost:5000/api/revenueПовторно используйте роль
Hannah.curl -H "X-MS-API-ROLE: Hannah" http://localhost:5000/api/revenue
Тестирование с помощью GraphQL
Контекст сеанса также работает с запросами GraphQL.
query {
revenues {
items {
id
category
revenue
accessible_role
}
}
}
Передайте заголовок роли:
curl -X POST http://localhost:5000/graphql \
-H "Content-Type: application/json" \
-H "X-MS-API-ROLE: Oscar" \
-d '{"query": "{ revenues { items { id category revenue accessible_role } } }"}'
Что построитель API данных отправляет в SQL Server
Если контекст сеанса включен, построитель данных задает значения контекста сеанса для каждого запроса перед выполнением запроса.
EXEC sp_set_session_context 'roles', 'Oscar', @read_only = 0;
-- Then executes your query
SELECT * FROM dbo.Revenues;
Все утверждения пользователей, прошедшие проверку подлинности, отправляются в виде пар "ключ-значение". Распространенные утверждения включают roles, sub или oid, и любые пользовательские утверждения от поставщика удостоверений.
Тестирование в SQL
Проверьте фильтр и предикат в SQL напрямую, чтобы убедиться, что он работает.
Снова подключитесь к СЕРВЕРУ SQL Server с помощью предпочтительного клиента или средства.
Запустите
sp_set_session_context, чтобы вручную задать требование контекста сеансаrolesстатическим значениемOscar.EXEC sp_set_session_context 'roles', 'Oscar';Выполните типичный
SELECT *запрос. Обратите внимание, что результаты автоматически фильтруются с помощью предиката.SELECT * FROM dbo.Revenues;(Необязательно) Запросите таблицу с помощью хранимой процедуры.
EXEC dbo.GetRevenuesForCurrentRole;
Очистите ресурсы
Если вы хотите удалить примеры объектов, выполните следующую команду:
DROP SECURITY POLICY IF EXISTS dbo.RevenuesSecurityPolicy;
DROP FUNCTION IF EXISTS dbo.RevenuesPredicate;
DROP PROCEDURE IF EXISTS dbo.GetRevenuesForCurrentRole;
DROP TABLE IF EXISTS dbo.Revenues;
Устранение неполадок
-
Нет возвращаемых результатов: убедитесь, что политика безопасности активна (
SELECT * FROM sys.security_policies), проверьте значение контекста сеанса (SELECT SESSION_CONTEXT(N'roles')) и убедитесь, что--set-session-context trueзадано в конфигурации построителя данных API. -
Все возвращенные строки: убедитесь, что политика безопасности не отключена (
WITH STATE = OFF) и что предикат возвращается1только для авторизованных строк. -
Проблемы с производительностью: индексируйте столбец предиката (
accessible_role) и рассмотрите возможность временного отключения политики для изоляции влияния на производительность.