Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Fabric Apps usa o decorador @role para anexar regras de autorização diretamente aos teus modelos de dados. As permissões são seguras em termos de tipos, propícias à refatorização e compiladas automaticamente na configuração subjacente de acesso a dados.
Antes de começar
- Compreenda a diferença entre autenticação (quem é) e autorização (o que pode fazer)
- Veja Configurar autenticação para configurar a verificação de identidade
- Compreenda a visão geral dos modelos de dados para conceitos básicos de entidades
Funções incorporadas
Fabric Apps reconhece a função integrada authenticated. Também pode definir papéis personalizados nas suas políticas quando necessário.
| Função | Descrição | Caso de utilização |
|---|---|---|
authenticated |
Requer uma sessão de utilizador válida com autenticação Fabric | Dados específicos do utilizador, recursos protegidos |
O @role decorador
Aplique @role ao nível da classe para controlar que funções podem executar que ações sobre uma entidade:
@role(roleName, actions, options?)
Parameters
| Parâmetro | Tipo | Descrição |
|---|---|---|
roleName |
string |
O nome da função, como 'authenticated' ou uma função de aplicação personalizada |
actions |
string \| string[] |
Ação simples ou matriz: 'create', 'read', 'update', 'delete', ou '*' para todo |
options |
object |
Objeto opcional com check, include, e exclude propriedades |
Exemplo básico
Restringa os utilizadores autenticados aos seus próprios dados:
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;
}
Neste exemplo:
- Os utilizadores autenticados só podem aceder a itens Todo em que
userIdcorresponde à declaraçãosubdo respetivo JWT.
Expressões de políticas seguras por tipos
O policy callback fornece acesso digitado tanto aos campos de reivindicações como de entidade. O TypeScript infere o tipo de entidade a partir da classe decorada, dando-te autocompletamento e segurança de refatoração:
policy: (claims, item) => claims.sub.eq(item.userId)
Reivindicações suportadas
| Afirmação | Descrição | Valor de exemplo |
|---|---|---|
claims.sub |
Identificador do assunto (ID de utilizador) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Endereço de e-mail do usuário | user@contoso.com |
claims.role |
Papel do utilizador (se fornecido pelo fornecedor de identidade) | admin |
Operadores de expressão
| Operador | Example | Descrição |
|---|---|---|
.eq() |
claims.sub.eq(item.userId) |
Verificação de igualdade |
Operadores lógicos
Combine expressões com .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))
})
Ambos os lados estão automaticamente entre parênteses para agrupamento correto.
Permissões ao nível de campo
Especifique os campos a que uma função pode aceder usando include ou exclude nas opções de função.
Incluir campos específicos
Permitir o title campo apenas durante as operações de criação:
@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;
}
Excluir campos específicos
Oculte campos sensíveis das operações de leitura:
@entity()
@role('authenticated', 'read', {
exclude: ['lastLogin', 'passwordHash'],
})
export class User {
@uuid() id!: string;
@text() email!: string;
@date({ optional: true }) lastLogin?: Date;
@text() passwordHash!: string;
}
Observação
As matrizes de campos são tipadas de acordo com os nomes reais das propriedades da entidade. Renomear um campo origina um erro em tempo de compilação em todas as listas include ou exclude que lhe fazem referência.
Permissões específicas de ação
Aplique regras diferentes por ação usando vários @role decoradores:
@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;
}
Esta configuração:
-
Criar: Apenas o criador pode criar, e apenas os campos
titleecontentsão permitidos. - Leitura: Só o criador pode ler os seus próprios documentos.
-
Atualização: Só o criador pode atualizar, mas não pode modificar
adminNotes. - Eliminar: Só o criador pode apagar.
Como funcionam as permissões
-
Recolha de metadados: O
@roledecorador recolhe metadados de permissão quando a classe é definida. -
Geração de esquemas: Quando executa
db apply, a CLI lê metadados e gera a configuração de permissões. -
Compilação de políticas: Os callbacks de políticas TypeScript são compilados em expressões de políticas de acesso a dados (por exemplo,
@claims.sub eq @item.userId). - Imposição em tempo de execução: A camada de acesso a dados impõe permissões a cada pedido à API.
-
Deteção de conflitos: Vários
@roledecoradores na mesma classe são agregados por função, com avisos para declarações conflitantes.
Padrões comuns
Acesso exclusivo ao proprietário
@entity()
@role('authenticated', '*', {
policy: (claims, item) => claims.sub.eq(item.ownerId)
})
export class PrivateNote {
@uuid() id!: string;
@text() ownerId!: string;
@text() content!: string;
}
Acesso total para utilizadores autenticados
@entity()
@role('authenticated', '*')
export class BlogPost {
@uuid() id!: string;
@text() title!: string;
@text() content!: string;
}
anulação pelo administrador
@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;
}
Os administradores podem modificar qualquer recurso, mas só os administradores podem apagar.
Passos seguintes
- Configurar autenticação para configurar fornecedores de identidade
- Consultar dados com GraphQL para testar consultas protegidas por permissão
- Referência de comandos CLI para comandos de geração de esquema