Microsoft SQL Server
Radnivå säkerhet
Sök…
RLS-filterpredikat
Med Sql Server 2016+ och Azure Sql-databasen kan du automatiskt filtrera rader som returneras i utvalda uttalanden med hjälp av något predikat. Denna funktion kallas säkerhetsnivå på rad .
Först behöver du en tabellvärderad funktion som innehåller något predikat som beskriver vad det är villkoret som gör att användare kan läsa data från någon tabell:
DROP FUNCTION IF EXISTS dbo.pUserCanAccessCompany
GO
CREATE FUNCTION
dbo.pUserCanAccessCompany(@CompanyID int)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
SELECT 1 as canAccess WHERE
CAST(SESSION_CONTEXT(N'CompanyID') as int) = @CompanyID
)
I det här exemplet säger predikatet att endast användare som har ett värde i SESSION_CONTEXT som matchar ingångsargument kan komma åt företaget. Du kan sätta vilket annat villkor som helst som t.ex. kontrollerar databasrollen eller databas_id för den aktuella användaren etc.
Det mesta av koden ovan är en mall som du kommer att kopiera och klistra in. Det enda som kommer att förändras här är namnet och argumenten för predikat och villkor i VAR-klausulen. Nu skapar du säkerhetspolicy som kommer att tillämpa detta predikat på någon tabell.
Nu kan du skapa säkerhetspolicy som kommer att tillämpa predikat i någon tabell:
CREATE SECURITY POLICY dbo.CompanyAccessPolicy
ADD FILTER PREDICATE dbo.pUserCanAccessCompany(CompanyID) ON dbo.Company
WITH (State=ON)
Denna säkerhetspolicy tilldelar predikat till företagstabellen. När någon försöker läsa data från företagstabellen kommer säkerhetspolicy att tillämpa predikat på varje rad, passera CompanyID-kolumnen som en parameter för predikatet och predikatet kommer att utvärdera om denna rad ska returneras i resultatet av SELECT-frågan.
Ändra säkerhetspolicy för RLS
Säkerhetspolicy är en grupp predikat kopplade till tabeller som kan hanteras tillsammans. Du kan lägga till, ta bort predikat eller slå på / av hela policyn.
Du kan lägga till fler predikat på tabeller i den befintliga säkerhetspolicyn.
ALTER SECURITY POLICY dbo.CompanyAccessPolicy
ADD FILTER PREDICATE dbo.pUserCanAccessCompany(CompanyID) ON dbo.Company
Du kan släppa några predikat från säkerhetspolicyn:
ALTER SECURITY POLICY dbo.CompanyAccessPolicy
DROP FILTER PREDICATE ON dbo.Company
Du kan inaktivera säkerhetspolicy
ALTER SECURITY POLICY dbo.CompanyAccessPolicy WITH ( STATE = OFF );
Du kan aktivera säkerhetspolicy som har inaktiverats:
ALTER SECURITY POLICY dbo.CompanyAccessPolicy WITH ( STATE = ON );
Förhindra uppdatering med hjälp av RLS-blockpredikat
Med säkerhetsnivå på rad kan du definiera vissa predikat som kommer att styra vem som kan uppdatera rader i tabellen. Först måste du definiera någon tabellvärdefunktion som representerar predikatet för att wll kontrollera åtkomstpolicy.
SKAPA FUNKTION
dbo.pUserCanAccessProduct (@CompanyID int)
RETURNS TABLE
WITH SCHEMABINDING
SOM ÅTERGÅNG (VÄLJ 1 som canAccess WHERE
CAST (SESSION_CONTEXT (N'CompanyID ') som int) = @CompanyID
) I det här exemplet säger predikatet att endast användare som har ett värde i SESSION_CONTEXT som matchar ingångsargument kan komma åt företaget. Du kan sätta vilket annat villkor som helst som t.ex. kontrollerar databasrollen eller databas_id för den aktuella användaren etc.
Det mesta av koden ovan är en mall som du kommer att kopiera och klistra in. Det enda som kommer att förändras här är namnet och argumenten för predikat och villkor i VAR-klausulen. Nu skapar du säkerhetspolicy som kommer att tillämpa detta predikat på någon tabell.
Nu kan vi skapa säkerhetspolicy med predikatet som kommer att blockera uppdateringar på produkttabellen om CompanyID-kolumnen i tabellen inte uppfyller predikatet.
SKAPA SÄKERHETSPOLITIK dbo.ProductAccessPolicy LÄGG TILL BLOCK PREDIKAT dbo.pUserCanAccessProduct (CompanyID) PÅ dbo.Product
Detta predikat kommer att tillämpas på alla operationer. Om du vill använda predikat på någon operation kan du skriva något som:
SKAPA SÄKERHETSPOLITIK dbo.ProductAccessPolicy LÄGG TILL BLOCK PREDIKAT dbo.pUserCanAccessProduct (CompanyID) PÅ dbo.Produkt EFTER INSERT
Möjliga alternativ som du kan lägga till efter blockpredikatdefinition är:
[{EFTER {INSERT | UPPDATERING } }
| {FÖR {UPPDATERA | DELETE}}]