SQL Server 2016: Row-Level Security

добавлено: 22 ноя 15
понравилось:0
просмотров: 2624
комментов: 0

теги:

Автор: Knyazev Alexey

Одна из интересных новинок в SQL Server 2016 - это Row-Level Security (RLS). Технология RLS (row-level security или безопасность на уровне строк) предоставляет возможность создания политик безопасности, которые ограничивают доступ пользователям к информации в БД.

Данная технология поддерживается во многих современных СУБД, но, к сожалению, в предыдущих версиях SQL Server реализовать RLS было не самой простой задачей. На сайте Microsoft есть целый документ, как это реализовать - http://download.microsoft.com/download/8/8/0/880F282A-AA4E-4351-83C0-DFFA3B56A19E/SQL_Server_RLS-CLS_White_paper.docx

Теперь рассмотрим, как это реализовано в SQL Server 2016

Создадим тестовую таблицу и наполним её данными:

if object_id ( N'dbo.TestRLS', N'U' ) is not null
drop table dbo.TestRLS;
go
create table dbo.TestRLS ( id int identity
                         , UserName sysname
                         , Val int
                         );
go
insert dbo.TestRLS 
values  ( 'User1', 11 ) 
      , ( 'User1', 12 )
      , ( 'User1', 13 )
      , ( 'User2', 21 )
      , ( 'User2', 22 )
      ;
go
select * from dbo.TestRLS;
go

Технология RLS состоит из 3-х компонентов:
Predicate function - Пользовательская функция описывает логику безопасности
Security predicate - Применяет предикат к конкретной таблице. Два типа: filter predicates and blocking predicates
Security policy - Коллекция предикатов для нескольких таблиц

Теперь создадим 2-х пользователей и дадим им права на чтение нашей таблицы

create user User1 without login;
create user User2 without login;
go
grant select on dbo.TestRLS to User1;
grant select on dbo.TestRLS to User2;
go

Создадим функцию (Predicate function), которая будет определять права

create function dbo.fn_securitypredicate(@user_name as sysname)
    returns table
with schemabinding
as
    return select 1 as fn_securitypredicate_result 
      where @user_name = user_name();
go

И теперь по имени пользователя будем определять, какие данные нам доступны:

create security policy rls_plicy
add filter predicate dbo.fn_securitypredicate(UserName) 
on dbo.TestRLS
with (state = on);
go

Посмотрим, какие данные видны в контексте каждого пользователя:

--Текущий пользователь
select user_name() as [user_name];
go
select * from dbo.TestRLS;
go

--Перевлючаем в контекст пользователя User1
execute as user = 'User1';
go
select user_name() as [user_name];
go
select * from dbo.TestRLS;
go
revert;
go

--Перевлючаем в контекст пользователя User2
execute as user = 'User2';
go
select user_name() as [user_name];
go
select * from dbo.TestRLS;
go
revert;
go

Всё достаточно легко и просто!

Комментарии




Необходимо войти на сайт, чтобы оставлять комментарии