Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Fabric Apps использует декоратор @role для привязки правил авторизации непосредственно к вашим моделям данных. Разрешения являются типобезопасными, рефакторными и автоматически компилируются в базовую конфигурацию доступа к данным.
Перед тем как начать
- Общие сведения о разнице между проверкой подлинности (кто вы являетесь) и авторизацией (что можно сделать).
- Ознакомьтесь с Настройка аутентификации, чтобы настроить проверку личности
- Ознакомьтесь с обзором моделей данных для понимания основ сущностей
Встроенные роли
Приложения Fabric распознает встроенную роль authenticated. При необходимости вы также можете задать пользовательские роли в своих политиках.
| Роль | Description | Сценарий использования |
|---|---|---|
authenticated |
Требуется действительный пользовательский сеанс с аутентификацией Fabric | Данные конкретного пользователя, защищённые ресурсы |
Декоратор @role
Примените @role на уровне класса, чтобы управлять тем, какие роли могут выполнять те или иные действия для сущности:
@role(roleName, actions, options?)
Parameters
| Parameter | Тип | Description |
|---|---|---|
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соответствует их утверждению JWTsub.
Типобезопасные выражения политик
Функция обратного вызова policy предоставляет типизированный доступ как к полям утверждений, так и к полям сущностей. TypeScript выводит тип сущности на основе декорированного класса, обеспечивая автодополнение и безопасность рефакторинга:
policy: (claims, item) => claims.sub.eq(item.userId)
Поддерживаемые утверждения
| Утверждение | Description | Пример значения |
|---|---|---|
claims.sub |
Идентификатор субъекта (идентификатор пользователя) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Адрес электронной почты пользователя | user@contoso.com |
claims.role |
Роль пользователя (если она предоставлена поставщиком удостоверений) | admin |
Операторы выражений
| Operator | Example | Description |
|---|---|---|
.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))
})
Обе стороны автоматически скобляются для правильной группировки.
Разрешения на уровне поля
Укажите поля, к которым роль может получить доступ с помощью include или exclude в настройках роли.
Включение определенных полей
Разрешить поле 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;
}
Замечание
Массивы полей типизированы фактическими именами свойств сущности. Переименование поля приводит к ошибке на этапе компиляции в каждом списке include или exclude, который ссылается на него.
Разрешения для конкретных действий
Применяйте разные правила к каждому действию с помощью нескольких декораторов @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 applyCLI считывает метаданные и создает конфигурацию разрешений. -
Компиляция политик: обратные вызовы политики 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;
}
Администраторы могут изменять любой ресурс, но только администраторы могут удалять их.
Дальнейшие действия
- Настройте аутентификацию, чтобы настроить поставщиков удостоверений
- Запрос данных с помощью GraphQL для тестирования запросов, защищенных разрешениями
- Справочник по командам CLI для генерации схем