Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Fabric Apps usa o decorador @role para anexar regras de autorização diretamente aos seus modelos de dados. As permissões são de tipo seguro, compatíveis com refatoração e compiladas automaticamente na configuração de acesso a dados subjacente.
Antes de começar
- Entenda a diferença entre autenticação (quem você é) e autorização (o que você pode fazer)
- Consulte Configurar autenticação para configurar a verificação de identidade
- Entenda visão geral dos modelos de dados para conceitos básicos de entidades
Funções incorporadas
Fabric Apps reconhece a função predefinida authenticated. Você também pode definir funções personalizadas em suas políticas quando necessário.
| Função | Description | Caso de uso |
|---|---|---|
authenticated |
Requer uma sessão de usuário válida com autenticação Fabric | Dados específicos do usuário, recursos protegidos |
O @role decorador
Aplique @role no nível da classe para controlar quais funções podem executar quais ações em uma entidade:
@role(roleName, actions, options?)
Parâmetros
| Parâmetro | Tipo | Description |
|---|---|---|
roleName |
string |
O nome da função, como 'authenticated' ou uma função de aplicativo personalizada |
actions |
string \| string[] |
Ação ou matriz única: 'create', , 'read', 'update', 'delete'ou '*' para todos |
options |
object |
Objeto opcional com check, includee exclude propriedades |
Exemplo básico
Restrinja os usuários 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 usuários autenticados só podem acessar itens Todo cujo
userIdcorresponda à declaraçãosubdo JWT.
Expressões de política de segurança de tipo
O policy callback fornece acesso tipado a campos de declarações e de entidades. O TypeScript infere o tipo de entidade da classe decorada, oferecendo-lhe segurança de preenchimento automático e refatoração:
policy: (claims, item) => claims.sub.eq(item.userId)
Declarações com suporte
| Reclamação | Description | Valor de exemplo |
|---|---|---|
claims.sub |
Identificador de assunto (ID do usuário) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Endereço de email do usuário | user@contoso.com |
claims.role |
Função de usuário (se fornecida pelo provedor de identidade) | admin |
Operadores de expressão
| Operador | Exemplo | Description |
|---|---|---|
.eq() |
claims.sub.eq(item.userId) |
Verificação de igualdade |
Operadores lógicos
Combinar 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 são colocados entre parênteses automaticamente para garantir o agrupamento correto.
Permissões de nível de campo
Especifique os campos que uma função pode acessar usando include ou exclude nas opções de função.
Incluir campos específicos
Permitir somente o title campo 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
Ocultar campos confidenciais de 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;
}
Note
Arrays de campos são tipados com base nos nomes reais das propriedades da entidade. Renomear um campo gera um erro em tempo de compilação em cada lista include ou exclude que faz referência a ele.
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: somente o criador pode criar e somente
titleecontentcampos são permitidos. - Ler: Somente o criador pode ler seus próprios documentos.
-
Atualização: somente o criador pode atualizar, mas não pode modificar
adminNotes. - Excluir: somente o criador pode excluir.
Como funcionam as permissões
-
Coleção de metadados: o
@roledecorador coleta metadados de permissão quando a classe é definida. -
Geração de esquema: quando você executa
db apply, a CLI lê metadados e gera a configuração de permissão. -
Compilação de política: callbacks de política em TypeScript são compilados em expressões de política de acesso a dados (por exemplo,
@claims.sub eq @item.userId). - Imposição de tempo de execução: a camada de acesso a dados impõe permissões em cada solicitação de API.
-
Detecçã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 somente 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 completo para usuários autenticados
@entity()
@role('authenticated', '*')
export class BlogPost {
@uuid() id!: string;
@text() title!: string;
@text() content!: string;
}
Substituiçã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 somente os administradores podem excluir.
Próximas Etapas
- Configurar a autenticação para configurar provedores de identidade
- Consultar dados com o GraphQL para testar consultas protegidas por permissão
- Referência de comando da CLI para comandos de geração de esquema