Ορισμός δικαιωμάτων δεδομένων

Το Fabric Apps χρησιμοποιεί τον διακοσμητή @role για να επισυνάψει κανόνες εξουσιοδότησης απευθείας στα μοντέλα δεδομένων σας. Τα δικαιώματα είναι ασφαλή για τον τύπο, φιλικά προς τον ανακατασκευαστή και μεταγλωττίζονται αυτόματα στην υποκείμενη διαμόρφωση πρόσβασης δεδομένων.

Πριν ξεκινήσετε

Ενσωματωμένοι ρόλοι

Το Fabric Apps αναγνωρίζει τον ενσωματωμένο ρόλο authenticated. Μπορείτε επίσης να ορίσετε προσαρμοσμένους ρόλους στις πολιτικές σας όταν χρειάζεται.

Role Περιγραφή Υπόθεση χρήσης
authenticated Απαιτεί έγκυρη περίοδο λειτουργίας χρήστη με έλεγχο ταυτότητας Fabric Δεδομένα για συγκεκριμένους χρήστες, προστατευμένοι πόροι

Ο @role διακοσμητής

Εφαρμόστε @role σε επίπεδο κλάσης για να ελέγξετε ποιοι ρόλοι μπορούν να εκτελέσουν ποιες ενέργειες σε μια οντότητα:

@role(roleName, actions, options?)

Παράμετροι

Παράμετρος Δακτυλογραφώ Περιγραφή
roleName string Το όνομα του ρόλου, όπως 'authenticated' ή ένας προσαρμοσμένος ρόλος εφαρμογής
actions string \| string[] Μία ενέργεια ή πίνακας: 'create', 'read', 'update', 'delete'ή '*' για όλους
options object Προαιρετικό αντικείμενο με check, includeκαι exclude ιδιότητες

Βασικό παράδειγμα

Περιορίστε τους εξουσιοδοτημένους χρήστες στα δικά τους δεδομένα:

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

Σε αυτό το παράδειγμα:

  • Οι πιστοποιημένοι χρήστες μπορούν να έχουν πρόσβαση μόνο σε στοιχεία Todo όπου userId ταιριάζει με την αξίωσή τους JWT sub .

Εκφράσεις πολιτικής ασφαλούς τύπου

Η policy επιστροφή κλήσης παρέχει πληκτρολογημένη πρόσβαση τόσο στα πεδία αξιώσεων όσο και στα πεδία οντοτήτων. Το TypeScript συνάγει τον τύπο οντότητας από τη διακοσμημένη κλάση, παρέχοντάς σας ασφάλεια αυτόματης συμπλήρωσης και αναδιαμόρφωσης:

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

Υποστηριζόμενες αξιώσεις

Ισχυρισμός Περιγραφή Τιμή παραδείγματος
claims.sub Αναγνωριστικό θέματος (αναγνωριστικό χρήστη) 00000000-0000-0000-0000-000000000001
claims.email Διεύθυνση ηλεκτρονικού ταχυδρομείου χρήστη user@contoso.com
claims.role Ρόλος χρήστη (εάν παρέχεται από τον πάροχο ταυτότητας) admin

Τελεστές παράστασης

Τελεστής Παράδειγμα Περιγραφή
.eq() claims.sub.eq(item.userId) Έλεγχος ισότητας

Λογικοί τελεστές

Συνδυάστε εκφράσεις με .and() και .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))
})

Και οι δύο πλευρές τοποθετούνται αυτόματα σε παρένθεση για σωστή ομαδοποίηση.

Δικαιώματα σε επίπεδο πεδίου

Καθορίστε τα πεδία στα οποία μπορεί να έχει πρόσβαση ένας ρόλος χρησιμοποιώντας includeexclude ή στις επιλογές ρόλου.

Συμπερίληψη συγκεκριμένων πεδίων

Να επιτρέπεται το πεδίο μόνο κατά τη title διάρκεια των λειτουργιών δημιουργίας:

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

Εξαίρεση συγκεκριμένων πεδίων

Απόκρυψη ευαίσθητων πεδίων από λειτουργίες ανάγνωσης:

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

Σημείωση

Οι πίνακες πεδίων πληκτρολογούνται με βάση τα πραγματικά ονόματα ιδιοτήτων της οντότητας. Η μετονομασία ενός πεδίου παράγει ένα σφάλμα χρόνου μεταγλώττισης σε κάθε includeexclude λίστα ή λίστα που αναφέρεται σε αυτό.

Δικαιώματα για συγκεκριμένες ενέργειες

Εφαρμόστε διαφορετικούς κανόνες ανά ενέργεια χρησιμοποιώντας πολλούς @role διακοσμητές:

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

Αυτή η διαμόρφωση:

  • Δημιουργία: Μόνο ο δημιουργός μπορεί να δημιουργήσει και επιτρέπονται μόνο title τα content πεδία.
  • Διαβάστε: Μόνο ο δημιουργός μπορεί να διαβάσει τα δικά του έγγραφα.
  • Ενημέρωση: Μόνο ο δημιουργός μπορεί να ενημερώσει, αλλά δεν μπορεί να τροποποιήσει adminNotesτο .
  • Διαγραφή: Μόνο ο δημιουργός μπορεί να διαγράψει.

Πώς λειτουργούν τα δικαιώματα

  • Συλλογή μεταδεδομένων: Ο @role διακοσμητής συλλέγει μεταδεδομένα δικαιωμάτων όταν ορίζεται η κλάση.
  • Δημιουργία σχήματος: Όταν εκτελείτε db applyτο , το CLI διαβάζει μετα-δεδομένα και δημιουργεί διαμόρφωση δικαιωμάτων.
  • Μεταγλώττιση πολιτικής: Οι επανακλήσεις πολιτικής TypeScript μεταγλωττίζονται σε εκφράσεις πολιτικής πρόσβασης δεδομένων (για παράδειγμα, @claims.sub eq @item.userId).
  • Επιβολή χρόνου εκτέλεσης: Το επίπεδο πρόσβασης δεδομένων επιβάλλει δικαιώματα σε κάθε αίτημα API.
  • Ανίχνευση διενέξεων: Πολλοί @role διακοσμητές στην ίδια κλάση συγκεντρώνονται ανά ρόλο, με προειδοποιήσεις για αντικρουόμενες δηλώσεις.

Συνήθη μοτίβα

Πρόσβαση μόνο για τον ιδιοκτήτη

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

Πλήρης πρόσβαση για πιστοποιημένους χρήστες

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

Παράκαμψη διαχειριστή

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

Οι διαχειριστές μπορούν να τροποποιήσουν οποιονδήποτε πόρο, αλλά μόνο οι διαχειριστές μπορούν να διαγράψουν.

Επόμενα βήματα