TGViewer
Zen of Python Zen of Python @zen_of_python · 18.8K subscribers
Post #4362 2.6K
Построчная безопасность (Row-Level Security) в SQL

RLS — одна из ключевых функций SQL, позволяющая реализовать контроль доступа на уровне отдельных строк таблицы. Вместо того чтобы писать сложные фильтры в каждом запросе, вы можете централизованно задать политику безопасности, которая будет автоматически применяться при чтении или изменении данных. Это упрощает архитектуру приложений и делает защиту данных более надежной.

Зачем это нужно

Обычно контроль доступа к данным реализуется в коде приложения. Например, чтобы пользователи видели только свои записи, вы добавляете фильтр WHERE user_id = @current_user. Но что, если по какой-то причине фильтр не применится? Чувствительные данные могут стать «достоянием общественности».

С помощью RLS вы перекладываете этот контроль внутрь базы данных. БД сама будет фильтровать строки в зависимости от настроек безопасности — даже если разработчик забудет что-то учесть в запросе.

Как работает RLS

Механизм реализуется через два ключевых механизма:

— Функция фильтрации определяет, какие строки доступны пользователю;
— Политика безопасности (Security Policy) привязывает эту функцию к конкретной таблице и операциям (SELECT, INSERT, UPDATE, DELETE).

Когда вы выполняете запрос к таблице с активной политикой RLS, SQL неявно вызывает фильтрующую функцию для каждой строки и исключает те, доступ к которым запрещён.

Пример

Шаг 1: Подготовка таблицы


CREATE TABLE Sales (
Id INT,
Amount MONEY,
Region NVARCHAR(50)
);


Шаг 2: Создание функции фильтрации


CREATE FUNCTION fn_securitypredicate(@Region AS NVARCHAR(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS result WHERE @Region = SESSION_CONTEXT(N'region');


Эта функция возвращает строку только в том случае, если регион совпадает с регионом, записанным в сессии.

Шаг 3: Создание политики безопасности


CREATE SECURITY POLICY SalesFilter
ADD FILTER PREDICATE dbo.fn_securitypredicate(Region) ON dbo.Sales
WITH (STATE = ON);


Теперь каждый запрос к таблице Sales автоматически фильтруется.

Шаг 4: Установка параметра в сессии


EXEC sp_set_session_context 'region', 'West';
SELECT * FROM Sales; -- покажет только строки с Region = 'West'


Advanced RLS: Безопасность

Можно создать отдельную блокирующую политику (Block Predicate), чтобы запретить изменения недопустимых строк:


CREATE FUNCTION fn_blockpredicate(@Region AS NVARCHAR(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS result WHERE @Region = SESSION_CONTEXT(N'region');

CREATE SECURITY POLICY SalesBlocker
ADD BLOCK PREDICATE dbo.fn_blockpredicate(Region) ON dbo.Sales
AFTER INSERT, UPDATE
WITH (STATE = ON);


Теперь пользователь не сможет вставить или изменить строку, если не имеет на это права.

#основы
  • 🔥 7
  • ❤ 1
  • ✍ 1
More from @zen_of_python
  1. Sep 27, 2026Как запускать собственный SQL через миграции Django У models.Index нашлось необычное приме…
  2. Sep 27, 2026Как разделить синхронный и асинхронный Python-клиенты При переписывании akismet автор отка…
  3. Sep 27, 2026Как заменить цепочку isinstance на singledispatch Когда обработка типов разрастается, цепо…
  4. Sep 26, 2026Как собирать динамические фильтры Django через Q-объекты Q() представляет условие для SQL-…
  5. Sep 26, 2026Почему str.splitlines() видит больше переносов, чем чтение файла У Python два разных понят…
  6. Sep 26, 2026Как вручную разрешить ленивый импорт в Python У объекта, созданного через lazy import json…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →