Tentukan izin data

Fabric Apps menggunakan dekorator @role untuk melampirkan aturan otorisasi langsung ke model data Anda. Izin aman terhadap tipe, mudah direfaktor, dan secara otomatis dikompilasi menjadi konfigurasi akses data yang mendasari.

Sebelum Anda mulai

Peran bawaan

Fabric Apps mengenali peran authenticated bawaan. Anda juga dapat menentukan peran kustom dalam kebijakan Anda saat diperlukan.

Peran Deskripsi Skenario penggunaan
authenticated Memerlukan sesi pengguna yang valid dengan autentikasi Fabric Data khusus pengguna, sumber daya yang dilindungi

Dekorator @role

Terapkan @role di tingkat kelas untuk mengontrol peran mana yang dapat melakukan tindakan mana pada entitas:

@role(roleName, actions, options?)

Parameters

Parameter Tipe Deskripsi
roleName string Nama peran, seperti 'authenticated' atau peran aplikasi kustom
actions string \| string[] Tindakan tunggal atau larik: 'create', 'read', 'update', 'delete', atau '*' untuk semua
options object Objek opsional dengan properti check, include, dan exclude

Contoh dasar

Batasi pengguna yang diautentikasi ke data mereka sendiri:

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

Dalam contoh ini:

  • Pengguna yang terautentikasi hanya dapat mengakses item Todo yang nilai userId-nya cocok dengan klaim JWT sub mereka.

Ekspresi kebijakan jenis aman

Panggilan policy balik menyediakan akses yang ditik ke bidang klaim dan entitas. TypeScript menyimpulkan jenis entitas dari kelas yang didekorasi, memberi Anda pelengkapan otomatis dan keamanan refaktor:

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

Klaim yang didukung

Tuntutan Deskripsi Contoh nilai
claims.sub Pengidentifikasi subjek (ID pengguna) 00000000-0000-0000-0000-000000000001
claims.email Alamat email pengguna user@contoso.com
claims.role Peran pengguna (jika disediakan oleh penyedia identitas) admin

Operator ekspresi

Operator Example Deskripsi
.eq() claims.sub.eq(item.userId) Pemeriksaan kesetaraan

Operator logis

Gabungkan ekspresi dengan .and() dan .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))
})

Kedua sisi secara otomatis diapit tanda kurung agar pengelompokan benar.

Izin tingkat bidang

Tentukan bidang yang dapat diakses peran menggunakan include atau exclude dalam opsi peran.

Sertakan bidang tertentu

Hanya izinkan kolom title selama operasi pembuatan:

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

Mengecualikan bidang tertentu

Sembunyikan bidang sensitif dari operasi baca:

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

Nota

Array field ditentukan tipenya sesuai dengan nama properti aktual entitas. Mengganti nama bidang menghasilkan kesalahan waktu kompilasi di setiap include atau exclude daftar yang mereferensikannya.

Izin khusus untuk tindakan tertentu

Terapkan aturan yang berbeda per tindakan menggunakan beberapa @role dekorator:

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

Konfigurasi ini:

  • Buat: Hanya pembuat yang dapat melakukan pembuatan, dan hanya bidang title dan content yang diizinkan.
  • Membaca: Hanya pembuat yang dapat membaca dokumen milik mereka sendiri.
  • Pembaruan: Hanya pembuat yang dapat memperbarui, tetapi tidak dapat mengubah adminNotes.
  • Hapus: Hanya pembuat yang dapat menghapus.

Bagaimana izin berfungsi

  • Pengumpulan metadata: Dekorator @role mengumpulkan metadata izin saat kelas didefinisikan.
  • Pembuatan skema: Saat Anda menjalankan db apply, CLI membaca metadata dan menghasilkan konfigurasi izin.
  • Kompilasi kebijakan: Panggilan balik kebijakan TypeScript dikompilasi ke dalam ekspresi kebijakan akses data (misalnya, @claims.sub eq @item.userId).
  • Penegakan saat runtime: Lapisan akses data menegakkan izin pada setiap permintaan API.
  • Deteksi konflik: Beberapa @role dekorator pada kelas yang sama dikelompokkan berdasarkan peran, dengan peringatan jika ada deklarasi yang bertentangan.

Pola umum

Akses khusus pemilik

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

Akses penuh untuk pengguna terautentikasi

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

Pengesampingan admin

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

Admin dapat memodifikasi sumber daya apa pun, tetapi hanya admin yang dapat menghapus.

Langkah berikutnya