Въведение
Организациите стават все по-загрижени за това как да намалят разходите за лицензиране на решения за бази данни с помощта на консолидация. В SQL Server може да се постигне известна консолидация, просто като се възползвате от съществуващата връзка един към много между екземпляри и бази данни. Въпреки това, има случаи, когато решението изисква данните да се консолидират в една таблица. В такъв случай може да има опасения относно това как да ограничите достъпа до данните.
Защитата на ниво ред беше въведена в SQL Server 2016 като решение за сценарии, подобни на горните. Позволява ви да ограничите достъпа до редове в таблица въз основа на условия, дефинирани във вградена функция с стойност на таблица, наречена предикатна функция . Когато предикатна функция се приложи към потребителска таблица, съдържаща консолидирани данни, системата може да бъде конфигурирана да връща различни набори от данни на различни потребители в зависимост от техните роли, което от своя страна зависи от техните длъжностни характеристики или отдели например.
Сценарий
Ще изградим прост сценарий, за да илюстрираме тази концепция с помощта на финансова институция. Банка реши да консолидира сметки за всички свои клиенти в единна база данни и Транзакциите таблицата е една разделена таблица, съдържаща всички транзакции, както и Клиентите таблица за съхранение на всички клиенти на банката. Банката се намира в няколко държави и също се разширява. Всяка държава се идентифицира с Идентификатор на партньор колона. Компанията е структурирана така, че достъпът до ключови таблици е ограничен въз основа на старшинството.
Идентифициране на защитени елементи
Ще трябва да внедрим решение за защита на ниво ред, което ограничава достъпа до данните за клиента и транзакциите въз основа на роли и политика за сигурност на ниво ред. Първата ни стъпка е да създадем необходимите таблици. Списък 1 показва DDL за ключовите таблици, които ще тестваме. Цялата база данни, използвана за този тест, може да бъде изтеглена от тук.
Listing 1 – Core Tables in West African Commercial Bank Database; -- Customers; create table Customers (CustID int identity (1000,1) not null Primary Key ,FirstName varchar(100) ,LastName varchar(100) ,PhoneNo bigint ,ContactAddress varchar(4000) ,AffiliateID char(3) foreign key references Affiliates(AffiliateID) ,AccountNo1 bigint ,AccountNo2 bigint ,AccountNo3 bigint ,AccountNo1Curr char (3) ,AccountNo2Curr char (3) ,AccountNo3Curr char (3) ) GO -- Transactions; create table Transactions (TranID int identity (1000,1) not null ,AcctID int foreign key references Accounts (AcctID) ,TranDate datetime ,TranAmt money ,AffiliateID char(3) foreign key references Affiliates(AffiliateID) ,primary key (TranID,TranDate)) ON PartSch (TranDate) -- Transaction_History; create table Transaction_History (TranID int identity (1000,1) not null ,AcctID int foreign key references Accounts (AcctID) ,TranDate datetime ,TranAmt money ,AffiliateID char(3) foreign key references Affiliates(AffiliateID) ,primary key (TranID,TranDate)) ON PartSch (TranDate)
След това създаваме набор от таблици, които можем да използваме за идентифициране на персонала. При тази настройка всеки персонал има ScopeID което определя до каква степен той или тя може да преглежда или манипулира данни:
- Национално – Служителят може да манипулира данни само в държавата на служителя (където той или тя работи)
- Регионален – Служителят може да манипулира данни само в региона на служителя (напр. Западна Африка)
- Глобално – Служител може да манипулира данни във всяка страна, където банката някога ще има клон
Всеки обхват се възлага на персонала въз основа на тяхното назначение. Обхватът на мениджъра на група е Глобален , обхватът на държавен мениджър е регионален и обхватът на изпълнителния директор е национален . Традиционният начин за ограничаване на достъпа до данни често е използването на роли и разрешения. Присвояването на разрешения на роля и последващото присвояване на ролята на потребител означава, че потребителят има разрешенията, свързани с тази роля за целия набор от данни във въпросната таблица. Защитата на ниво ред ни дава възможност да направим нещо по-подробно:ограничаване на разрешенията SELECT/UPDATE/DELETE на потребителя до подмножество от набора от данни в таблицата (финен контрол на достъпа).
Фиг. 1. StaffScope и таблици за персонал
Роли и потребители в базата данни
Списък 2 показва потребителите и ролите, които трябва да създадем, за да продължим с нашето решение. Идеята е, че има връзка между персонала, съхранен в потребителските таблици Staff и StaffScope и принципите на базата данни, които тези служители в крайна сметка ще използват за достъп до данните. Обърнете внимание на колоната на фиг. 1, наречена DBUserID . Тази колона се попълва с помощта на функцията DATABASE_PRINCIPAL_ID (вижте листинг 2)
Listing 2 – Staff, Database User IDs and Roles -- Populate Staff Table use WACB go insert into Staff values ('John','Edu',DATABASE_PRINCIPAL_ID(),'Manager','233205678493','2','Accra, Ghana','EGH'); insert into Staff values ('Margaret','Harrison',DATABASE_PRINCIPAL_ID(),'Group Manager','2348030006574','3','Lagos, Nigeria','ENG'); insert into Staff values ('Edward','Antwi',DATABASE_PRINCIPAL_ID(),'Executive','22824567493','1','Lome, Togo','ETG'); insert into Staff values ('Barbara','Orji',DATABASE_PRINCIPAL_ID(),'Executive','22424567493','1','Abuja, Nigeria','ENG'); GO -- Create Database User IDs for Staff create user jedu without login; create user mharrison without login; create user eantwi without login; create user borji without login; -- Associate Database Principal IDs with Staff update staff set DBUserID=DATABASE_PRINCIPAL_ID(concat(left(firstname,1),lastname)); -- Create Database Roles create role [National] ; create role [Regional] ; create role [Global] ; -- Grant Permissions on Desired Tables to Database Roles grant select on customers to [National]; grant select, update on customers to Regional; grant select, update on customers to Global; grant select on Transactions to Regional, Global; grant select on Transaction_History to Regional, Global; grant update on Transactions to Global; -- Grant Database Roles to Database Users Associated with Staff alter role [National] add member eantwi; alter role [National] add member borji; alter role [Regional] add member jedu; alter role [Global] add member mharrison;
Дотук в обобщение това, което направихме е:
- Създайте/определете таблиците, които трябва да защитим
- Създайте таблици, които посочват критериите, които ще използваме, за да ограничим достъпа до данни на ниво ред (обхват)
- Създадени роли на база данни и потребители, към които ще приложим ограничения
- Ограничен достъп до основните таблици („Сигурност на ниво таблица“) с помощта на роли и разрешения
Функция за прогнозиране и политика за сигурност
Досега имаме това, което можем да наречем сигурност на ниво таблица, реализирано с помощта на роли и разрешения. Сега искаме да отидем по-дълбоко. Искаме двама принципали, които имат привилегии SELECT на таблица, да могат да правят заявки за таблицата, но да виждат различни набори от данни въз основа на условията, които сме настроили. Обява 3 ни показва как постигаме това.
Listing 3 - Implement Row Level Security -- Create Predicate Function create schema rls; go create function rls.AccessPredicate (@AffiliateID char(3)) returns table with schemabinding as return select 1 as access from dbo.Staff as s join dbo.StaffScope ss on s.ScopeID=ss.ScopeID join dbo.Affiliates a on s.AffiliateID=a.AffiliateID where ( IS_MEMBER('National')=1 and s.DBUserID=DATABASE_PRINCIPAL_ID() and @AffiliateID=s.AffiliateID ) OR ( IS_MEMBER('Regional')=1 and @AffiliateID in (select a.AffiliateID from dbo.Affiliates where Region='West Africa') ) OR ( IS_MEMBER('Global')=1 ); GO -- Create Security Policy create security policy rls.dataSecurityPol add filter predicate rls.AccessPredicate (AffiliateID) on dbo.Customers, add filter predicate rls.AccessPredicate (AffiliateID) on dbo.Transactions, add filter predicate rls.AccessPredicate (AffiliateID) on dbo.Transaction_History, add block predicate rls.AccessPredicate (AffiliateID) on dbo.Customers after update, add block predicate rls.AccessPredicate (AffiliateID) on dbo.Transactions after update, add block predicate rls.AccessPredicate (AffiliateID) on dbo.Transaction_History after update; GO -- Alter Security Policy alter security policy rls.dataSecurityPol add filter predicate rls.AccessPredicate (AffiliateID) on dbo.Transaction_History, add block predicate rls.AccessPredicate (AffiliateID) on dbo.Transaction_History after update; GO
Предикатната функция дефинира условията, които трябва да бъдат изпълнени, за да може принципал да види подмножество от интересните данни. В тази функция има три условия:
- Потребителят на базата данни на персонала е член на Националния роля и AffiliateID съвпада с това на персонала ИЛИ
- Потребителят на базата данни на персонала е член на Регионалния роля и AffiliateID съответства на списъка с AffiliateID принадлежащи към Западноафриканския регион ИЛИ
- Потребителят на базата данни на персонала е член на Global
Това означава, че член на Global Ролята вижда всички данни, просто защото той или тя принадлежи към тази роля. Въпреки това членовете на другите две роли трябва да отговарят на допълнителни критерии, граничещи с AffiliateID .
За да бъде полезна функцията, приложете това към таблици като предикати FILTER или предикати BLOCK. Предикатите FILTER ограничават това, което принципалът може да види, докато предикатите BLOCK гарантират, че принципалът не може да манипулира никакви данни извън тези, които са му/й представени от ограниченията, дефинирани във функцията. Политиката за сигурност е контейнер, в който указваме предикатите FILTER и BLOCK за всички таблици, които ни интересуват. Разгледайте листинг 3 отново.
Един много интересен аспект на този подход е модулността. Можем да приложим предикатите към допълнителни таблици в политиката за сигурност, без да засягаме съществуващите дефинирани таблици, можем да добавим нови принципали на база данни (персонал), като създадем потребители на база данни и им предоставим съответните роли. Когато възникне движение на персонала, можем да актуализираме назначенията на ролите и т.н.
Тестване на внедряването
Така че сега, когато сме готови, можем да се представяме за принципалите на базата данни, за да определим дали имаме очакваните резултати, използвайки кода в листинг 4. Преди да разгледаме това, нека видим ролите, свързани с всеки персонал и техните филиали на фиг. 2.
Фиг. 2. Списък на персонала
Listing 4 – Testing the Implementation select * from Customers; execute ('select * from Customers') as user='eantwi'; execute ('select * from Customers') as user='borji'; execute ('select * from Customers') as user='jedu'; execute ('select * from Customers') as user='mharrison';
В първия ред правя заявка към Клиентите таблица като системен администратор, но не получавам РЕДОВЕ. Това означава, че дори администратор не може да отмени ефекта на RLS без да се представя за друго лице.
Фиг. 4. SysAdmin не вижда редове
Барбара и Едуард са изпълнителни директори и принадлежат към Националния обхват, но работят в различни държави, така че виждат клиентите, свързани със съответните им филиали. (Вижте имената на персонала на фиг. 1).
Фиг. 5. Ръководителите виждат редовете на своите партньори
Джон и Маргарет са мениджъри на държави и групи. Те принадлежат към регионалния и Глобални Обхвати съответно. Джон вижда данни за Западна Африка, докато Маргарет вижда данни за всички региони.
Фиг. 6. Мениджърите виждат редовете на своя регион
Резултатите са еднакви за всички останали таблици, към които е приложена политиката за сигурност. Наблюдавайте това без разрешения в Транзакциите таблица, сигурността на ниво ред няма стойност.
Фиг. 7. Няма разрешения за SELECT за Транзакции Таблица
Listing 5 – Permissions on Transactions Table grant select on dbo.Transactions to [National];
Фиг. 8. Транзакции Таблица, както се вижда от ръководителите
Заключение
Защитата на ниво ред е мощен метод за използване на фините възможности за контрол на достъпа на SQL Server. Използването на тази функция изисква да използвате SQL Server 2016 или по-нова версия. Както подсказва името, целта е да ограничите достъпа до редове в таблица, като използвате сложни заявки, след като сте се погрижили за „сигурността на ниво таблица“. Сценариите, в които тази способност може да се приложи, са безкрайни, поради което е много полезна за широк спектър от среди. Направете добре, за да проучите и да видите какво може да направи за вас.
Препратки
Исаков, В. (2018). Изпит Ref 70-764 Администриране на SQL инфраструктура на база данни . Pearson Education
Защита на ниво ред