Säkerhet på radnivå
Använd gruppmedlemskap eller körningskontext för att styra åtkomsten till rader i en databastabell.
Säkerheten på radnivå (RLS) förenklar design och kodning av säkerheten. Med den här funktionen kan du begränsa åtkomsten till datarader i ditt program. Du kan till exempel begränsa användaråtkomsten till rader som är relevanta för deras avdelning eller begränsa kundåtkomsten till endast de data som är relevanta för företaget.
Logiken för åtkomstbegränsning finns på databasnivån i stället för från data på en annan programnivå. Databassystemet tillämpar åtkomstbegränsningarna varje gång dataåtkomst görs från valfri nivå. Den här logiken gör ditt säkerhetssystem mer tillförlitligt och robust genom att minska säkerhetssystemets yta.
Med RLS kan du ge åtkomst till andra program och användare, endast till en viss del av en tabell. Du kanske till exempel vill:
- Bevilja endast åtkomst till rader som uppfyller vissa villkor
- Maskera data i vissa kolumner
- Alla alternativ ovan
Anteckning
När en RLS-princip är aktiverad i en tabell ersätts åtkomsten helt av den RLS-fråga som definieras i tabellen. Åtkomstbegränsningen gäller för alla användare, inklusive databasadministratörer och RLS-skaparen. RLS-frågan måste uttryckligen innehålla definitioner för alla typer av användare som du vill ge åtkomst till.
Mer information finns i hanteringskommandon för hantering av säkerhetsprincipen på radnivå.
Tips
Dessa funktioner är ofta användbara för row_level_security frågor:
Begränsningar
- Det finns ingen gräns för hur många tabeller som säkerhetsprincipen på radnivå kan konfigureras för.
- Det går inte att konfigurera en säkerhetsprincip på radnivå i externa tabeller.
- RLS-principen kan inte aktiveras i en tabell under följande omständigheter:
- När den refereras av en uppdateringsprincipfråga , medan uppdateringsprincipen inte har konfigurerats med en hanterad identitet.
- När det refereras av en kontinuerlig export som använder en annan autentiseringsmetod än personifiering.
- När en åtkomstprincip för begränsad vy har konfigurerats för tabellen.
Exempel
Begränsa åtkomsten till tabellen Försäljning
I en tabell med namnet Sales
innehåller varje rad information om en försäljning. En av kolumnerna innehåller namnet på säljaren. I stället för att ge säljarna åtkomst till alla poster i Sales
aktiverar du en säkerhetsprincip på radnivå i den här tabellen för att endast returnera poster där säljaren är den aktuella användaren:
Sales | where SalesPersonAadUser == current_principal()
Du kan också maskera e-postadressen:
Sales | where SalesPersonAadUser == current_principal() | extend EmailAddress = "****"
Om du vill att alla säljare ska se all försäljning i ett visst land/region kan du definiera en fråga som liknar:
let UserToCountryMapping = datatable(User:string, Country:string)
[
"john@domain.com", "USA",
"anna@domain.com", "France"
];
Sales
| where Country in ((UserToCountryMapping | where User == current_principal_details()["UserPrincipalName"] | project Country))
Om du har en grupp som innehåller cheferna kanske du vill ge dem åtkomst till alla rader. Här är frågan för säkerhetsprincipen på radnivå.
let IsManager = current_principal_is_member_of('aadgroup=sales_managers@domain.com');
let AllData = Sales | where IsManager;
let PartialData = Sales | where not(IsManager) and (SalesPersonAadUser == current_principal()) | extend EmailAddress = "****";
union AllData, PartialData
Exponera olika data för medlemmar i olika Microsoft Entra grupper
Om du har flera Microsoft Entra grupper och vill att medlemmarna i varje grupp ska se olika delmängder av data använder du den här strukturen för en RLS-fråga.
Customers
| where (current_principal_is_member_of('aadgroup=group1@domain.com') and <filtering specific for group1>) or
(current_principal_is_member_of('aadgroup=group2@domain.com') and <filtering specific for group2>) or
(current_principal_is_member_of('aadgroup=group3@domain.com') and <filtering specific for group3>)
Tillämpa samma RLS-funktion på flera tabeller
Definiera först en funktion som tar emot tabellnamnet som en strängparameter och refererar till tabellen med operatorn table()
.
Exempel:
.create-or-alter function RLSForCustomersTables(TableName: string) {
table(TableName)
| ...
}
Konfigurera sedan RLS på flera tabeller på det här sättet:
.alter table Customers1 policy row_level_security enable "RLSForCustomersTables('Customers1')"
.alter table Customers2 policy row_level_security enable "RLSForCustomersTables('Customers2')"
.alter table Customers3 policy row_level_security enable "RLSForCustomersTables('Customers3')"
Skapa ett fel vid obehörig åtkomst
Om du vill att icke-auktoriserade tabellanvändare ska få ett fel i stället för att returnera en tom tabell använder du assert()
funktionen . I följande exempel visas hur du skapar det här felet i en RLS-funktion:
.create-or-alter function RLSForCustomersTables() {
MyTable
| where assert(current_principal_is_member_of('aadgroup=mygroup@mycompany.com') == true, "You don't have access")
}
Du kan kombinera den här metoden med andra exempel. Du kan till exempel visa olika resultat för användare i olika Microsoft Entra grupper och skapa ett fel för alla andra.
Kontrollera behörigheter för uppföljningsdatabaser
Den RLS-princip som du konfigurerar på produktionsdatabasen börjar också gälla i de följande databaserna. Du kan inte konfigurera olika RLS-principer för produktions- och uppföljningsdatabaserna. Du kan dock använda current_cluster_endpoint()
funktionen i din RLS-fråga för att uppnå samma effekt, som att ha olika RLS-frågor i följartabeller.
Exempel:
.create-or-alter function RLSForCustomersTables() {
let IsProductionCluster = current_cluster_endpoint() == "mycluster.eastus.kusto.windows.net";
let DataForProductionCluster = TempTable | where IsProductionCluster;
let DataForFollowerClusters = TempTable | where not(IsProductionCluster) | extend EmailAddress = "****";
union DataForProductionCluster, DataForFollowerClusters
}
Anteckning
RLS-funktionen ovan har ingen som helst prestandapåverkan på frågor i leader-klustret. Prestandapåverkan på frågor på följande kluster påverkas endast av DataForFollowerClusters
komplexiteten i .
Fler användningsfall
- En kundtjänst kan identifiera uppringare med flera siffror i sitt personnummer. Det här numret ska inte vara helt exponerat för supporten. En RLS-princip kan tillämpas på tabellen för att maskera alla utom de sista fyra siffrorna i personnumret i resultatuppsättningen för en fråga.
- Ange en RLS-princip som maskerar personligt identifierbar information (PII) och gör det möjligt för utvecklare att köra frågor mot produktionsmiljöer i felsökningssyfte utan att bryta mot efterlevnadsreglerna.
- Ett sjukhus kan ange en RLS-princip som gör det möjligt för sjuksköterskor att visa datarader endast för sina patienter.
- En bank kan ange en RLS-princip för att begränsa åtkomsten till finansiella datarader baserat på en medarbetares affärsdivision eller roll.
- Ett program för flera innehavare kan lagra data från många klienter i en enda tabelluppsättning (vilket är effektivt). De skulle använda en RLS-princip för att framtvinga en logisk separation av varje klients datarader från alla andra klientorganisationers rader, så att varje klientorganisation bara kan se sina datarader.
Prestandapåverkan på frågor
När en RLS-princip är aktiverad i en tabell kommer prestanda att påverka frågor som har åtkomst till tabellen. Åtkomsten till tabellen ersätts av den RLS-fråga som har definierats i tabellen. Prestandaeffekten för en RLS-fråga består normalt av två delar:
- Medlemskapskontroller i Microsoft Entra ID: Kontrollerna är effektiva. Du kan kontrollera medlemskap i tiotals eller till och med hundratals grupper utan större inverkan på frågeprestandan.
- Filter, kopplingar och andra åtgärder som tillämpas på data: Effekten beror på frågans komplexitet
Exempel:
let IsRestrictedUser = current_principal_is_member_of('aadgroup=some_group@domain.com');
let AllData = MyTable | where not(IsRestrictedUser);
let PartialData = MyTable | where IsRestrictedUser and (...);
union AllData, PartialData
Om användaren inte är en del av some_group@domain.comIsRestrictedUser
utvärderas till false
. Frågan som utvärderas liknar den här:
let AllData = MyTable; // the condition evaluates to `true`, so the filter is dropped
let PartialData = <empty table>; // the condition evaluates to `false`, so the whole expression is replaced with an empty table
union AllData, PartialData // this will just return AllData, as PartialData is empty
IsRestrictedUser
Om utvärderas till true
utvärderas på samma sätt endast frågan förPartialData
.
Förbättra frågeprestanda när RLS används
- Om ett filter tillämpas på en kolumn med hög kardinalitet, till exempel DeviceID, bör du överväga att använda partitioneringsprincip eller radordningsprincip
- Om ett filter tillämpas på en kolumn med låg eller medelhög kardinalitet bör du överväga att använda radordningsprincipen
Prestandapåverkan på inmatning
Inmatningen påverkas inte av prestanda.
Feedback
https://aka.ms/ContentUserFeedback.
Kommer snart: Under hela 2024 kommer vi att fasa ut GitHub-problem som feedbackmekanism för innehåll och ersätta det med ett nytt feedbacksystem. Mer information finns i:Skicka och visa feedback för