Въпроси и отговори за RLS

- RLS_ALL потребител
- Добавяне на потребители
- Премахване на потребители
- Съвети и трикове
|
1. RLS_ALL потребител
RLS_ALL е специален потребител на базата данни без никакво свързване на вход в сървъра. Това означава, че не можете да влезете в SQL Server с него.
Единственият начин да го използвате е с EXECUTE AS USER = 'RLS_ALL'
Той има достъп до всички данни, които са разделени от функционалността на RLS.
Този потребител се използва, например, за създаване на агрегати на данни, притежавани от множество потребители.
Например, отчет за общите продажби на всички служители за година, но всеки служител може да вижда само своите собствени продажби.
За потребител на пантеон да може да използва EXECUTE AS USER = 'RLS_ALL', той трябва да има разрешения GRANT IMPERSONATE на потребителя RLS_ALL.
Само потребители в Пантеон трябва да имат разрешения GRANT IMPERSONATE.
Даването на тези разрешения на вградени акаунти в SQL Server (като SA и т.н.) обикновено не е необходимо.
- Само потребители на Пантеон могат да четат данни от таблици, защитени от RLS
Потребителят SA (ако не е свързан с потребител PA) няма достъп до защитени данни.
Всякакви данни, защитени от RLS, могат да бъдат четени само от потребител PA с подходящи разрешения.
За да използвате външни връзки към базата данни, връзката с базата данни трябва да бъде направена с потребител PANTHEON, свързан с потребителя на базата данни.
2. Добавяне на потребители
Добавяне на потребители за достъп до други приложения в базата данни PANTHEON.
Можем да добавим потребител с PANTHEON:
Вижте следните инструкции: Добавяне на потребител и Настройване на разрешения за потребител.
За по-сложни настройки, където искаме да добавим потребител в множество бази данни.
Добавяне на потребител и зареждане на разрешения без права. Настройваме разрешенията на потребителя с PANTHEON:
declare
@v_cUserId sysname =
#UserName#
, @p_lang_id varchar(2)
--
, @p_subject varchar(30) = NULL
--
, @p_user_id int = NULL
, @p_contact_id int = NULL
BEGIN
select * from [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
SET @p_user_id = (SELECT anUserId FROM [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId);
set @p_contact_id = NULL;
IF (@p_user_id IS NULL)
BEGIN
Exec ppa_user_create @v_cUserId, @v_cUserId, 1;
select @p_subject = P.acOurCompany, @p_lang_id = PS.acLocalization from tPA_SysParam P, tPA_SysParamSys PS;
SELECT @p_user_id = anUserId FROM [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
EXEC [dbo].[ppa_user_save]
@p_user_id = @p_user_id OUTPUT -- @p_user_id int OUTPUT
, @p_contact_id = @p_contact_id OUTPUT -- @p_contact_id int OUTPUT
, @p_user_name = @v_cUserId -- sysname
, @p_lang_id = @p_lang_id -- varchar(2)
, @p_active = 'T' -- char(1)
, @p_license_server = Null -- sysname = NULL
, @p_license_database = Null -- sysname = NULL
, @p_profile = Null -- varchar(10) = NULL
, @p_additpersonmark = Null -- varchar(100) = NULL
, @p_code = Null -- varchar(20)= NULL
, @p_pin = Null -- varchar(11) = NULL
, @p_foreigner = 'F'
--
, @p_subject = @p_subject -- varchar(30) = NULL
, @p_name = @v_cUserId -- varchar(30) = NULL
, @p_surName = @v_cUserId -- varchar(30) = NULL
;
exec [dbo].[ppa_security_insert] @p_user_id, False, False;--без разрешения
exec ppa_security_save @p_user_id, False, False;
print @p_user_id
exec [dbo].[ppa_authorization_security_save]
NULL -- @p_authorization varchar(50)
, @p_user_id -- @p_principal_id int
, 0 -- @p_principal_type bit
, NULL -- @p_parent_id varchar(50)
, 0 -- @p_acquired bit
, 0 -- @p_inherited bit
, 0 -- @p_permission_select bit
, 0 -- @p_permission_update bit
, 0 -- @p_permission_delete bit
, 32767 -- @p_permission_update_period int
, 1 -- @p_propagate_entities bit = 0
, Null -- @p_licence char(2) = 'MF'
exec pPA_SysSQLLoginPswdChange @v_cUserId, Null, @v_cUserId;
EXEC sp_addrolemember N'db_owner', @v_cUserId;
EXEC sp_addrolemember N'db_datawriter', @v_cUserId;
EXEC sp_addrolemember N'db_datareader', @v_cUserId;
end;
select * from [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
select * from tPA_SetDoctypeUserSecurity where anUserId = @p_user_id;
end;
3. Премахване на потребители
declare
@v_cUserId sysname = #USER#,
@command nvarchar(max);
begin
select * from [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
delete from [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
IF (DATABASE_PRINCIPAL_ID(@v_cUserId) IS NOT NULL)
BEGIN
SET @command = N'DROP USER ' + QUOTENAME(@v_cUserId) + N';'
EXEC(@command);
END;
IF (SUSER_ID(@v_cUserId) IS NOT NULL)
BEGIN
SET @command = N'DROP LOGIN ' + QUOTENAME(@v_cUserId) + N';'
EXEC(@command);
END;
select * from [dbo].[tHE_SetSubjContact] WHERE acUserId = @v_cUserId;
end;
4. Съвети и трикове
С активирането на Row Level Security (RLS) в SQL Server, това добавя лесно разделение на потребителските данни, но добавя малко сложност на плана за изпълнение на заявките за всяка заявка, която използва таблиците, на които е активиран RLS.
Целта е да се минимизира сложността на плана за изпълнение на заявките.
- Използване в съхранени процедури
Избягвайте много обединения с таблици RLS. Ако трябва да обедините много таблици, по-добре е да обедините няколко (2-4 таблици), да поставите резултата в временна таблица (която може дори да бъде правилно индексирана) и да обедините тази временна таблица с други таблици.
Това ще улесни работата на оптимизатора на заявки, тъй като заявката е разделена на множество части.
- Използване в тригери
В тригерите след изпълнение няма нужда да се обединявате с основната таблица, за да получите данните.
За оператори за актуализиране или вмъкване, псевдотаблицата "вмъкнати" вече съдържа нови стойности, които също са в основната таблица.
Така че всичко, което трябва да направите, е да се обедините с нея.
Ако имате сценарий, в който трябва да проверите за съществуването на някакви данни в тригер и да актуализирате данни на базата на тази проверка, по-добре е да поставите резултатите от проверката в временна таблица, да проверите дали тези данни удовлетворяват желаното условие и да ги използвате за актуализиране на основната таблица.
- Поддръжка на вградени функции на SQL Server за паралелизъм
Ако някога трябва да проверите потребителско име или SQL вход, под който текущият контекст се изпълнява, използвайте следните функции в операторите SELECT.
Те са единствените, които поддържат паралелизъм в плановете за изпълнение на SQL Server:
USER_NAME, CURRENT_USER, SUSER_NAME, SUSER_SNAME, SUSER_ID, SUSER_SID.
Всяка друга вградена функция предотвратява разглеждането на паралелни планове за изпълнение на заявки.