Dela via


Säkerhetsprincip på radnivå

Gäller för: ✅Microsoft FabricAzure Data Explorer

Använd gruppmedlemskap eller körningskontext för att styra åtkomsten till rader i en databastabell.

Säkerhet på radnivå (RLS) förenklar utformningen och kodningen av säkerhet. Du kan använda begränsningar för dataradsåtkomst 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 deras företag.

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
  • Anonymisera data i några av kolumnerna
  • Alla ovanstående

Not

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 att hantera säkerhetsprincipen på radnivå.

Dricks

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å på externa tabeller.
  • RLS-principen kan inte aktiveras i en tabell under följande omständigheter:
  • RLS-frågan kan inte referera till andra tabeller som har en säkerhetsprincip på radnivå aktiverad.
  • RLS-frågan kan inte referera till tabeller som finns i andra databaser.

Exempel

Begränsa åtkomsten till tabellen Försäljning

I en tabell med namnet Salesinnehå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 Salesaktiverar 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/en viss 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 en annan delmängd 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().

Till 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 funktionen assert(). 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 i 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 funktionen current_cluster_endpoint() i RLS-frågan för att uppnå samma effekt, som att ha olika RLS-frågor i följartabeller.

Till 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
}

Not

RLS-funktionen ovan har ingen som helst prestandapåverkan på frågor i leader-klustret. Prestandapåverkan på frågor på följarkluster påverkas endast av komplexiteten i DataForFollowerClusters.

Kontrollera behörigheter för genvägsdatabaser

Den RLS-princip som du konfigurerar i produktionsdatabasen börjar också gälla i genvägsdatabaserna. Du kan inte konfigurera olika RLS-principer för produktions- och genvägsdatabaserna. Du kan dock använda funktionen current_cluster_endpoint() i RLS-frågan för att uppnå samma effekt, som att ha olika RLS-frågor i genvägstabeller.

Till 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
}

Not

RLS-funktionen ovan har ingen som helst prestandapåverkan på frågor i källdatabasen. Prestandapåverkan på frågor på genvägsdatabaserna påverkas endast av komplexiteten i DataForFollowerClusters.

Fler användningsfall

  • En kundtjänst kan identifiera uppringare med flera siffror i deras personnummer. Det här numret ska inte vara helt exponerat för supportpersonen. En RLS-princip kan tillämpas på tabellen för att maskera alla utom de sista fyra siffrorna i personnummer 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 fråga produktionsmiljöer i felsökningssyfte utan att bryta mot efterlevnadsreglerna.
  • Ett sjukhus kan ange en RLS-princip som gör att sjuksköterskor endast kan visa datarader för sina patienter.
  • En bank kan ange en RLS-princip för att begränsa åtkomsten till finansiella datarader baserat på en anställds affärsdivision eller roll.
  • Ett program med flera klientorganisationer 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 uppdelning 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 det att finnas en viss prestandapåverkan på frågor som har åtkomst till tabellen. Åtkomsten till tabellen ersätts av den RLS-fråga som definieras i tabellen. Prestandapåverkan för en RLS-fråga består normalt av två delar:

  • Medlemskapskontroller i Microsoft Entra-ID: Kontroller är effektiva. Du kan kontrollera medlemskap i tiotals eller till och med hundratals grupper utan större påverkan på frågeprestandan.
  • Filter, kopplingar och andra åtgärder som tillämpas på data: Effekten beror på frågans komplexitet

Till 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 ingår i some_group@domain.comutvärderas IsRestrictedUser 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

Om IsRestrictedUser utvärderas till trueutvärderas på samma sätt endast frågan för PartialData.

Förbättra frågeprestanda när RLS används

Prestandapåverkan på inmatning

Det finns ingen prestandapåverkan på inmatning.