Definujte dátové oprávnenia

Fabric Apps používa dekorátor @role na pripojenie autorizačných pravidiel priamo k vašim dátovým modelom. Oprávnenia sú typovo bezpečné, vhodné na refaktorovanie a automaticky sa kompilujú do základnej konfigurácie prístupu k dátam.

Skôr než začnete

Vstavané úlohy

Fabric Apps rozpoznáva zabudované funkcie authenticated a anonymous úlohy. Môžete si tiež definovať vlastné roly vo svojich politikách, keď je to potrebné.

Rola Description Prípad použitia
authenticated Vyžaduje platnú používateľskú reláciu s Fabric autentifikáciou Používateľsky špecifické dáta, chránené zdroje
anonymous Umožňuje prístup bez platnej používateľskej relácie. Pre viac informácií pozri Anonymný prístup k dátam v Fabric aplikáciách. Verejné údaje a neoverené skúsenosti

Dekoratér @role

Aplikovať @role na úrovni triedy na kontrolu, ktoré roly môžu vykonávať ktoré akcie na entite:

@role(roleName, actions, options?)

Parametre

Parameter Typ Description
roleName string Názov roly, napríklad 'authenticated' alebo vlastná aplikačná rola
actions string \| string[] Jednoakčná činnosť alebo pole: 'create', 'read', 'update', 'delete', alebo '*' pre všetky
options object Voliteľný objekt s check, include, a vlastnosťami exclude

Základný príklad

Obmedzte overených používateľov na ich vlastné údaje:

import { entity, role, uuid, text } from '@microsoft/rayfin-core';

@entity()
@role('authenticated', ['create', 'read', 'update', 'delete'], {
  policy: (claims, item) => claims.sub.eq(item.userId),
})
export class Todo {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) description?: string;
  @text() userId!: string;
}

V tomto príklade:

  • Autentifikovaní používatelia majú prístup len k položkám ToDo, ktoré zodpovedajú userId ich nároku JWT sub .

Typovo bezpečné politické výrazy

Callback policy poskytuje typový prístup k poľám nárokov aj entít. TypeScript odvodzuje typ entity z dekorovanej triedy, čím vám poskytuje automatické dopĺňanie a refaktorovanie bezpečnosti:

policy: (claims, item) => claims.sub.eq(item.userId)

Podporené tvrdenia

Deklarácia Description Ukážková hodnota
claims.sub Identifikátor subjektu (používateľské ID) 00000000-0000-0000-0000-000000000001
claims.email Používateľská e-mailová adresa user@contoso.com
claims.role Rola používateľa (ak poskytuje poskytovateľ identity) admin

Operátory výrazov

Operátor Príklad Description
.eq() claims.sub.eq(item.userId) Kontrola rovnosti

Logické operátory

Spojte výrazy s .and() a .or():

// User must own the item AND item must be active
@role('authenticated', 'read', {
  policy: (claims, item) =>
    claims.sub.eq(item.userId).and(item.isActive.eq(true))
})

// User is admin OR user owns the item
@role('authenticated', ['update', 'delete'], {
  policy: (claims, item) =>
    claims.role.eq('admin').or(claims.sub.eq(item.ownerId))
})

Obe strany sú automaticky zaradené do zátvoriek pre správne zoskupenie.

Povolenia na úrovni poľa

Špecifikujte polia, ku ktorým môže rola pristupovať pomocou include alebo exclude v nastaveniach roly.

Zahrňte konkrétne polia

Povoľte title pole len počas operácií vytvárania:

@entity()
@role('authenticated', 'create', {
  policy: (claims, item) => claims.sub.eq(item.createdBy),
  include: ['title'],
})
export class Document {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) content?: string;
  @text() createdBy!: string;
}

Vylúčiť konkrétne polia

Skrytie citlivých polí pred čítacími operáciami:

@entity()
@role('authenticated', 'read', {
  exclude: ['lastLogin', 'passwordHash'],
})
export class User {
  @uuid() id!: string;
  @text() email!: string;
  @date({ optional: true }) lastLogin?: Date;
  @text() passwordHash!: string;
}

Poznámka

Polia polí sú zadané podľa skutočných názvov vlastností entity. Premenovanie poľa spôsobuje chybu v čase kompilácie v každom include zozname exclude , ktorý naň odkazuje.

Povolenia špecifické pre akciu

Aplikujte rôzne pravidlá na každú akciu pomocou viacerých @role dekorátorov:

@entity()
@role('authenticated', 'create', {
  policy: (claims, item) => claims.sub.eq(item.createdBy),
  include: ['title', 'content'],
})
@role('authenticated', 'read', {
  policy: (claims, item) => claims.sub.eq(item.createdBy),
})
@role('authenticated', 'update', {
  policy: (claims, item) => claims.sub.eq(item.createdBy),
  exclude: ['adminNotes'],
})
@role('authenticated', 'delete', {
  policy: (claims, item) => claims.sub.eq(item.createdBy),
})
export class SecureDocument {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) content?: string;
  @text({ optional: true }) adminNotes?: string;
  @text() createdBy!: string;
}

Táto konfigurácia:

  • Vytvoriť: Vytvoriť môže len tvorca, a title sú povolené len polia a content
  • Čítajte: Iba tvorca môže čítať svoje vlastné dokumenty.
  • Aktualizácia: Aktualizácie môže len tvorca, ale nemôže upravovať adminNotes.
  • Vymazať: Iba tvorca môže vymazať.

Ako fungujú oprávnenia

  • Zber metadát: Dekoratér @role zbiera metadáta povolení, keď je trieda definovaná.
  • Generovanie schémy: Keď spustíte db apply, CLI číta metadáta a generuje konfiguráciu oprávnení.
  • Kompilácia politík: Callbacky politík TypeScript sa kompilujú do výrazov politiky prístupu k dátam (napríklad @claims.sub eq @item.userId).
  • Vynucovanie za behu: Vrstva prístupu k dátam vynucuje oprávnenia na každý API požiadavok.
  • Detekcia konfliktov: Viacerí @role dekorátori na tej istej triede sú agregovaní pre každú rolu, s varovaniami pred protichodnými vyhláseniami.

Bežné vzory

Prístup iba pre vlastníka

@entity()
@role('authenticated', '*', {
  policy: (claims, item) => claims.sub.eq(item.ownerId)
})
export class PrivateNote {
  @uuid() id!: string;
  @text() ownerId!: string;
  @text() content!: string;
}

Plný prístup pre overených používateľov

@entity()
@role('authenticated', '*')
export class BlogPost {
  @uuid() id!: string;
  @text() title!: string;
  @text() content!: string;
}

Administratívne prepísanie

@entity()
@role('authenticated', ['create', 'read', 'update'], {
  policy: (claims, item) =>
    claims.role.eq('admin').or(claims.sub.eq(item.ownerId))
})
@role('authenticated', 'delete', {
  policy: (claims, _item) => claims.role.eq('admin')
})
export class ManagedResource {
  @uuid() id!: string;
  @text() ownerId!: string;
  @text() name!: string;
}

Administrátori môžu upravovať akýkoľvek zdroj, ale len administrátori môžu mazať.

Ďalšie kroky