Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Fabric Apps usa il decoratore @role per associare direttamente le regole di autorizzazione ai modelli di dati. Le autorizzazioni sono sicure rispetto ai tipi, compatibili con il refactoring e vengono compilate automaticamente nella configurazione sottostante per l'accesso ai dati.
Prima di iniziare
- Comprendere la differenza tra l'autenticazione (chi si è) e l'autorizzazione (cosa è possibile fare)
- Consulta Configurare l'autenticazione per configurare la verifica dell'identità
- Panoramica dei modelli di dati per informazioni di base sulle entità
Ruoli predefiniti
Fabric App riconosce il ruolo predefinito authenticated. È anche possibile definire ruoli personalizzati nei criteri quando necessario.
| Ruolo | Description | Caso di utilizzo |
|---|---|---|
authenticated |
Richiede una sessione utente valida con autenticazione Fabric | Dati specifici dell'utente, risorse protette |
Il decorator @role
Applicare @role a livello di classe per controllare quali ruoli possono eseguire le azioni su un'entità:
@role(roleName, actions, options?)
Parameters
| Parametro | Tipo | Description |
|---|---|---|
roleName |
string |
Nome del ruolo, ad esempio 'authenticated' o ruolo applicazione personalizzato |
actions |
string \| string[] |
Singola azione o matrice: 'create', 'read', 'update', 'delete'o '*' per tutti |
options |
object |
Oggetto facoltativo con proprietà check, include e exclude |
Esempio di base
Limitare gli utenti autenticati ai propri dati:
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 questo esempio:
- Gli utenti autenticati possono accedere solo agli elementi Todo in cui
userIdcorrisponde all'attestazione JWTsub.
Espressioni di criteri con controllo di tipo
Il callback policy consente l'accesso tipizzato sia alle dichiarazioni sia ai campi delle entità. TypeScript deduce il tipo dell'entità dalla classe decorata, offrendoti il completamento automatico e un refactoring sicuro:
policy: (claims, item) => claims.sub.eq(item.userId)
Attestazioni supportate
| Richiesta di rimborso | Description | Valore di esempio |
|---|---|---|
claims.sub |
Identificatore del soggetto (ID utente) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Indirizzo e-mail dell'utente | user@contoso.com |
claims.role |
Ruolo utente (se fornito dal provider di identità) | admin |
Operatori di espressione
| Operatore | Example | Description |
|---|---|---|
.eq() |
claims.sub.eq(item.userId) |
Controllo di uguaglianza |
Operatori logici
Combinare espressioni con .and() e .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))
})
Entrambi i lati sono racchiusi automaticamente tra parentesi per il raggruppamento corretto.
Autorizzazioni a livello di campo
Specificare i campi a cui un ruolo può accedere usando include o exclude nelle opzioni del ruolo.
Includi campi specifici
Consentire solo il campo title durante le operazioni di creazione:
@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;
}
Escludere campi specifici
Nascondere i campi sensibili dalle operazioni di lettura:
@entity()
@role('authenticated', 'read', {
exclude: ['lastLogin', 'passwordHash'],
})
export class User {
@uuid() id!: string;
@text() email!: string;
@date({ optional: true }) lastLogin?: Date;
@text() passwordHash!: string;
}
Note
Le matrici di campi vengono tipate in base ai nomi effettivi delle proprietà dell'entità. La ridenominazione di un campo genera un errore in fase di compilazione in ogni include elenco o exclude che vi fa riferimento.
Autorizzazioni specifiche dell'azione
Applica regole diverse per ogni azione usando più decoratori @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;
}
Questa configurazione:
-
Crea: solo il creatore può creare e sono consentiti solo i campi
titleecontent. - Lettura: solo l'autore può leggere i propri documenti.
-
Aggiornamento: solo l'autore può aggiornare, ma non può modificare
adminNotes. - Elimina: solo l'autore può eliminare.
Funzionamento delle autorizzazioni
-
Raccolta di metadati: l'elemento
@roleDecorator raccoglie i metadati delle autorizzazioni quando viene definita la classe . -
Generazione dello schema: quando si esegue
db apply, l'interfaccia della riga di comando legge i metadati e genera la configurazione delle autorizzazioni. -
Compilazione dei criteri: i callback dei criteri TypeScript vengono compilati in espressioni dei criteri di accesso ai dati (ad esempio,
@claims.sub eq @item.userId). - Imposizione del runtime: il livello di accesso ai dati applica le autorizzazioni per ogni richiesta API.
-
Rilevamento dei conflitti: più
@roledecoratori sulla stessa classe vengono aggregati in base al ruolo, con avvisi per dichiarazioni conflittuali.
Modelli comuni
Accesso solo proprietario
@entity()
@role('authenticated', '*', {
policy: (claims, item) => claims.sub.eq(item.ownerId)
})
export class PrivateNote {
@uuid() id!: string;
@text() ownerId!: string;
@text() content!: string;
}
Accesso completo per gli utenti autenticati
@entity()
@role('authenticated', '*')
export class BlogPost {
@uuid() id!: string;
@text() title!: string;
@text() content!: string;
}
Override per gli amministratori
@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;
}
Gli amministratori possono modificare qualsiasi risorsa, ma solo gli amministratori possono eliminare.
Passaggi successivi
- Configurare l'autenticazione per configurare i provider di identità
- Eseguire query sui dati con GraphQL per testare le query protette dall'autorizzazione
- Riferimento dei comandi CLI per i comandi di generazione dello schema