Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Fabric Apps używa dekoratora @role do dołączania reguł autoryzacji bezpośrednio do modeli danych. Uprawnienia zapewniają bezpieczeństwo typów, ułatwiają refaktoryzację i są automatycznie kompilowane do bazowej konfiguracji dostępu do danych.
Zanim rozpoczniesz
- Zrozumienie różnicy między uwierzytelnianiem (kim jesteś) i autoryzacją (co można zrobić)
- Zapoznaj się z artykułem Konfigurowanie uwierzytelniania w celu skonfigurowania weryfikacji tożsamości
- Omówienie modeli danych dla podstaw jednostek
Wbudowane role
Fabric Apps rozpoznaje wbudowaną rolę authenticated. W razie potrzeby można również zdefiniować role niestandardowe w zasadach.
| Role | Opis | Przypadek użycia |
|---|---|---|
authenticated |
Wymaga prawidłowej sesji użytkownika z uwierzytelnianiem Fabric | Dane specyficzne dla użytkownika, chronione zasoby |
Dekorator @role
Zastosuj @role na poziomie klasy, aby kontrolować, które role mogą wykonywać określone działania na encji:
@role(roleName, actions, options?)
Parameters
| Parametr | Typ | Opis |
|---|---|---|
roleName |
string |
Nazwa roli, taka jak 'authenticated' lub rola aplikacji niestandardowej |
actions |
string \| string[] |
Pojedyncza akcja lub tablica: 'create', 'read', 'update', 'delete' lub '*' dla wszystkich |
options |
object |
Opcjonalny obiekt z właściwościami check, includei exclude |
Przykład podstawowy
Ogranicz uwierzytelnionych użytkowników do własnych danych:
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;
}
W tym przykładzie:
- Uwierzytelnieni użytkownicy mogą uzyskiwać dostęp tylko do elementów Todo, w których wartość
userIdodpowiada roszczeniusubtokenu JWT.
Wyrażenia zasad bezpieczne pod względem typów
Funkcja wywołania zwrotnego policy zapewnia typowany dostęp zarówno do pól deklaracji, jak i pól encji. TypeScript wywnioskuje typ encji na podstawie dekorowanej klasy, co zapewnia autouzupełnianie i bezpieczeństwo refaktoryzacji:
policy: (claims, item) => claims.sub.eq(item.userId)
Obsługiwane roszczenia
| Roszczenie | Opis | Przykładowa wartość |
|---|---|---|
claims.sub |
Identyfikator podmiotu (identyfikator użytkownika) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Adres e-mail użytkownika | user@contoso.com |
claims.role |
Rola użytkownika (jeśli jest dostarczana przez dostawcę tożsamości) | admin |
Operatory wyrażeń
| Obsługujący | Example | Opis |
|---|---|---|
.eq() |
claims.sub.eq(item.userId) |
Sprawdzanie równości |
Operatory logiczne
Łączenie wyrażeń za pomocą .and() i .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))
})
Obie strony są automatycznie ujmowane w nawiasy w celu prawidłowego grupowania.
Uprawnienia na poziomie pola
Określ pola, do których rola może uzyskiwać dostęp za pomocą include opcji roli lub exclude .
Uwzględnij określone pola
Zezwalaj tylko na title pole podczas operacji tworzenia:
@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;
}
Wykluczanie określonych pól
Ukryj poufne pola przed operacjami odczytu:
@entity()
@role('authenticated', 'read', {
exclude: ['lastLogin', 'passwordHash'],
})
export class User {
@uuid() id!: string;
@text() email!: string;
@date({ optional: true }) lastLogin?: Date;
@text() passwordHash!: string;
}
Uwaga / Notatka
Tablice pól są typowane zgodnie z faktycznymi nazwami właściwości encji. Zmiana nazwy pola powoduje błąd kompilacji na każdej liście include lub exclude, która się do niego odwołuje.
Uprawnienia specyficzne dla akcji
Zastosuj różne reguły dla każdej akcji przy użyciu wielu dekoratorów @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;
}
Ta konfiguracja:
-
Utwórz: Tylko autor może tworzyć i dozwolone są tylko pola
titleicontent. - Odczyt: Tylko autor może odczytać własne dokumenty.
-
Aktualizacja: tylko twórca może aktualizować, ale nie może modyfikować
adminNoteselementu . - Usuń: tylko twórca może usunąć.
Jak działają uprawnienia
-
Kolekcja metadanych:
@roledekorator zbiera metadane uprawnień po zdefiniowaniu klasy. -
Generowanie schematu: po uruchomieniu
db applyinterfejs wiersza polecenia odczytuje metadane i generuje konfigurację uprawnień. -
Kompilacja zasad: wywołania zwrotne zasad TypeScript są kompilowane w wyrażeniach zasad dostępu do danych (na przykład
@claims.sub eq @item.userId). - Egzekwowanie w czasie wykonywania: warstwa dostępu do danych egzekwuje uprawnienia przy każdym żądaniu API.
-
Wykrywanie konfliktów: wiele dekoratorów
@rolew tej samej klasie jest grupowanych według ról, z ostrzeżeniami o sprzecznych deklaracjach.
Często używane wzorce
Dostęp wyłącznie dla właściciela
@entity()
@role('authenticated', '*', {
policy: (claims, item) => claims.sub.eq(item.ownerId)
})
export class PrivateNote {
@uuid() id!: string;
@text() ownerId!: string;
@text() content!: string;
}
Pełny dostęp dla uwierzytelnionych użytkowników
@entity()
@role('authenticated', '*')
export class BlogPost {
@uuid() id!: string;
@text() title!: string;
@text() content!: string;
}
Nadpisanie przez administratora
@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;
}
Administratorzy mogą modyfikować dowolny zasób, ale tylko administratorzy mogą usuwać.
Następne kroki
- Skonfiguruj uwierzytelnianie, aby skonfigurować dostawców tożsamości
- Wykonywanie zapytań dotyczących danych za pomocą języka GraphQL w celu przetestowania zapytań chronionych uprawnieniami
- Opis poleceń CLI dotyczących generowania schematu