Zabezpečení na úrovni řádků

Pomocí členství ve skupině nebo kontextu spuštění můžete řídit přístup k řádkům v tabulce databáze.

Zabezpečení na úrovni řádků (RRLS) zjednodušuje návrh a kódování zabezpečení. Umožňuje použít omezení přístupu k datovým řádkům v aplikaci. Můžete například omezit přístup uživatelů k řádkům, které jsou relevantní pro jejich oddělení, nebo omezit přístup zákazníka jenom k datům relevantním pro jejich společnost.

Logika omezení přístupu se nachází v databázové vrstvě, nikoli mimo data v jiné aplikační vrstvě. Databázový systém použije omezení přístupu při každém pokusu o přístup k datům z jakékoli vrstvy. Díky této logice je váš bezpečnostní systém spolehlivější a robustnější tím, že zmenšuje povrch vašeho systému zabezpečení.

Zabezpečení na úrovni řádků umožňuje poskytnout přístup jiným aplikacím a uživatelům, pouze k určité části tabulky. Můžete například chtít:

  • Udělení přístupu pouze řádkům, které splňují určitá kritéria
  • Anonymizace dat v některých sloupcích
  • Všechny výše uvedené možnosti

Poznámka

Pokud jsou pro tabulku povolené zásady zabezpečení na úrovni řádků, přístup se zcela nahradí dotazem RLS, který je v tabulce definovaný. Omezení přístupu platí pro všechny uživatele, včetně správců databází a tvůrce zabezpečení na úrovni řádků. Dotaz RLS musí explicitně obsahovat definice pro všechny typy uživatelů, kterým chcete udělit přístup.

Další informace najdete v tématu Příkazy pro správu zásad zabezpečení na úrovni řádků.

Tip

Tyto funkce jsou často užitečné pro row_level_security dotazy:

Omezení

  • Počet tabulek, pro které je možné nakonfigurovat zásady zabezpečení na úrovni řádků, není nijak omezený.
  • Zásady zabezpečení na úrovni řádků nelze konfigurovat u externích tabulek.
  • Zásady zabezpečení na úrovni řádků není možné povolit u tabulky za následujících okolností:

Příklady

Omezení přístupu k tabulce Sales

V tabulce s názvem Salesobsahuje každý řádek podrobnosti o prodeji. Jeden ze sloupců obsahuje jméno prodejce. Místo toho, abyste prodejcům udělili přístup ke všem záznamům v Sales, povolte v této tabulce zásadu zabezpečení na úrovni řádků tak, aby se vracely jenom záznamy, ve kterých je prodejce aktuálním uživatelem:

Sales | where SalesPersonAadUser == current_principal()

E-mailovou adresu můžete také zamaskovat:

Sales | where SalesPersonAadUser == current_principal() | extend EmailAddress = "****"

Pokud chcete, aby každý prodejce viděl všechny prodeje určité země nebo oblasti, můžete definovat dotaz podobný následujícímu:

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))

Pokud máte skupinu, která obsahuje manažery, můžete jim udělit přístup ke všem řádkům. Tady je dotaz na zásadu zabezpečení na úrovni řádků.

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

Zveřejnění různých dat členům různých skupin Microsoft Entra

Pokud máte více Microsoft Entra skupin a chcete, aby členové každé skupiny viděli jinou podmnožinu dat, použijte tuto strukturu pro dotaz RLS.

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>)

Použití stejné funkce zabezpečení na úrovni řádků na více tabulkách

Nejprve definujte funkci, která přijímá název tabulky jako parametr řetězce a odkazuje na tabulku pomocí operátoru table() .

Příklad:

.create-or-alter function RLSForCustomersTables(TableName: string) {
    table(TableName)
    | ...
}

Zabezpečení na úrovni řádků pak nakonfigurujte pro více tabulek tímto způsobem:

.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')"

Vytvoření chyby při neoprávněném přístupu

Pokud chcete, aby se neautorizovaným uživatelům tabulky místo vrácení prázdné tabulky zobrazila chyba, použijte assert() funkci . Následující příklad ukazuje, jak vytvořit tuto chybu ve funkci zabezpečení na úrovni řádků:

.create-or-alter function RLSForCustomersTables() {
    MyTable
    | where assert(current_principal_is_member_of('aadgroup=mygroup@mycompany.com') == true, "You don't have access")
}

Tento přístup můžete zkombinovat s dalšími příklady. Můžete například uživatelům zobrazit různé výsledky v různých Microsoft Entra skupinách a vytvořit chybu pro všechny ostatní.

Řízení oprávnění u databází sledujících

Zásady zabezpečení na úrovni řádků, které nakonfigurujete pro produkční databázi, se projeví také v databázích sledujících. V produkční databázi a databázi sledujících nemůžete nakonfigurovat různé zásady zabezpečení na úrovni řádků. Pomocí funkce v dotazu RLS ale můžete current_cluster_endpoint() dosáhnout stejného efektu, jako když budete mít různé dotazy RLS v tabulkách sledujících.

Příklad:

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

Poznámka

Výše uvedená funkce zabezpečení na úrovni řádků nemá žádný vliv na výkon dotazů v vedoucím clusteru. Dopad na výkon dotazů v clusterech sledujících bude ovlivněn pouze složitostí DataForFollowerClusters.

Další případy použití

  • Pracovník podpory v call centru může identifikovat volající podle několika číslic čísla sociálního pojištění. Toto číslo by nemělo být plně zveřejněné pracovníkovi podpory. V tabulce je možné použít zásadu zabezpečení na úrovni řádků, která v sadě výsledků libovolného dotazu zamaskuje všechny číslice čísla sociálního pojištění kromě posledních čtyř číslic.
  • Nastavte zásady zabezpečení na úrovni řádků, které maskují identifikovatelné osobní údaje (PII) a umožňují vývojářům dotazovat produkční prostředí pro účely řešení potíží bez porušení předpisů o dodržování předpisů.
  • Nemocnice může nastavit zásadu zabezpečení na úrovni řádků, která umožňuje sestrám zobrazit řádky dat pouze pro své pacienty.
  • Banka může nastavit zásady zabezpečení na úrovni řádků, které omezí přístup k řádkům s finančními daty na základě organizačního oddělení nebo role zaměstnance.
  • Aplikace s více tenanty může ukládat data z mnoha tenantů do jedné sady tabulek (což je efektivní). Pomocí zásad zabezpečení na úrovni řádků vynutí logické oddělení řádků dat každého tenanta od řádků každého druhého tenanta, aby každý tenant viděl jenom svoje datové řádky.

Dopad dotazů na výkon

Pokud je pro tabulku povolená zásada zabezpečení na úrovni řádků, bude to mít určitý dopad na výkon dotazů, které přistupují k této tabulce. Přístup k tabulce se nahradí dotazem zabezpečení na úrovni řádků definovaným v dané tabulce. Dopad dotazu RLS na výkon se obvykle skládá ze dvou částí:

  • Kontroly členství v Microsoft Entra ID: Kontroly jsou efektivní. Členství můžete kontrolovat v desítkách nebo i stovkách skupin, aniž by to mělo zásadní dopad na výkon dotazů.
  • Filtry, spojení a další operace použité na data: Dopad závisí na složitosti dotazu.

Příklad:

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

Pokud uživatel není součástí some_group@domain.com, vyhodnotí IsRestrictedUser se jako false. Vyhodnocovaný dotaz je podobný tomuto:

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

Podobně pokud IsRestrictedUser se vyhodnotí jako true, vyhodnotí se pouze dotaz na PartialData .

Zvýšení výkonu dotazů při použití zabezpečení na úrovni řádků

Dopad na výkon při příjmu dat

Příjem dat nemá žádný vliv na výkon.