Definieren von Datenberechtigungen

Fabric Apps verwendet den @role-Dekorateur, um Autorisierungsregeln direkt an Ihre Datenmodelle anzufügen. Berechtigungen sind typsicher, refactoringfreundlich und werden automatisch in die zugrunde liegende Datenzugriffskonfiguration kompiliert.

Bevor Sie anfangen

  • Verstehen des Unterschieds zwischen Authentifizierung (wer Sie sind) und Autorisierung (was Sie tun können)
  • Lesen Sie Authentifizierung konfigurieren, um die Identitätsprüfung einzurichten.
  • Machen Sie sich mit der Übersicht über Datenmodelle vertraut, um die Grundlagen von Entitäten zu verstehen.

Festgelegte Rollen

Fabric Apps erkennt die integrierte authenticated Rolle. Sie können bei Bedarf auch benutzerdefinierte Rollen in Ihren Richtlinien definieren.

Rolle Description Anwendungsfall
authenticated Erfordert eine gültige Benutzersitzung mit Fabric Authentifizierung Benutzerspezifische Daten, geschützte Ressourcen

Der @role Dekorateur

Wenden Sie @role auf Klassenebene an, um zu steuern, welche Rollen welche Aktionen für eine Entität durchführen können:

@role(roleName, actions, options?)

Parameters

Parameter Typ Description
roleName string Der Rollenname, z. B. 'authenticated' oder eine benutzerdefinierte Anwendungsrolle
actions string \| string[] Einzelne Aktion oder Matrix: 'create', , 'read', 'update', 'delete'oder '*' für alle
options object Optionales Objekt mit check, includeund exclude Eigenschaften

Einfaches Beispiel

Einschränken authentifizierter Benutzer auf ihre eigenen Daten:

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

In diesem Beispiel:

  • Authentifizierte Benutzer können nur auf Todo-Elemente zugreifen, bei denen userId mit ihrem JWT-Claim sub übereinstimmt.

Typensichere Richtlinienausdrücke

Der policy Rückruf bietet typierten Zugriff auf Anspruchs- und Entitätsfelder. TypeScript leitet den Entitätstyp aus der dekorierten Klasse ab und bietet Ihnen so Autovervollständigung und Refactoring-Sicherheit:

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

Unterstützte Ansprüche

Anspruch Description Beispielwert
claims.sub Antragsteller-ID (Benutzer-ID) 00000000-0000-0000-0000-000000000001
claims.email Benutzer-E-Mail-Adresse user@contoso.com
claims.role Benutzerrolle (sofern vom Identitätsanbieter bereitgestellt) admin

Ausdrucksoperatoren

Operator Example Description
.eq() claims.sub.eq(item.userId) Gleichheitsprüfung

Logische Operatoren

Kombinieren von Ausdrücken mit .and() und .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))
})

Beide Seiten werden zur korrekten Gruppierung automatisch in Klammern gesetzt.

Berechtigungen auf Feldebene

Geben Sie die Felder an, auf die eine Rolle zugreifen kann, mithilfe include oder exclude in den Rollenoptionen.

Einschließen bestimmter Felder

Lassen Sie das Feld title nur bei Erstellungsvorgängen zu:

@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;
}

Ausschließen bestimmter Felder

Sensible Felder bei Lesevorgängen ausblenden:

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

Hinweis

Feld-Arrays sind mit den tatsächlichen Eigenschaftsnamen der Entität typisiert. Das Umbenennen eines Felds führt in jeder include oder exclude Liste, die darauf verweist, zu einem Kompilierfehler.

Aktionsspezifische Berechtigungen

Wenden Sie unterschiedliche Regeln pro Aktion mit mehreren @role Dekoratoren an:

@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;
}

Diese Konfiguration:

  • Erstellen: Nur der Ersteller kann erstellen, und nur die titleFeldercontent sind zulässig.
  • Lesen: Nur der Ersteller kann eigene Dokumente lesen.
  • Update: Nur der Ersteller kann aktualisieren, aber adminNotes nicht ändern.
  • Löschen: Nur der Ersteller kann löschen.

Funktionsweise von Berechtigungen

  • Metadatensammlung: Der @role Dekorateur sammelt Berechtigungsmetadaten, wenn die Klasse definiert ist.
  • Schemagenerierung: Wenn Sie ausführen db apply, liest die CLI Metadaten und generiert die Berechtigungskonfiguration.
  • Richtlinienkompilierung: TypeScript-Richtlinienrückrufe werden in Datenzugriffsrichtlinienausdrücke kompiliert (z. B @claims.sub eq @item.userId. ).
  • Laufzeiterzwingung: Die Datenzugriffsebene erzwingt Berechtigungen für jede API-Anforderung.
  • Konflikterkennung: Mehrere @role Dekoratoren für derselben Klasse werden pro Rolle zusammengefasst, mit Warnungen bei widersprüchlichen Deklarationen.

Allgemeine Muster

Nur Besitzerzugriff

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

Vollzugriff für authentifizierte Benutzer

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

Außerkraftsetzung durch Administratoren

@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;
}

Administratoren können jede Ressource ändern, aber nur Administratoren können sie löschen.

Nächste Schritte