Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Fabric Apps usa el decorador de @role para adjuntar reglas de autorización directamente a los modelos de datos. Los permisos tienen seguridad de tipos, son fáciles de refactorizar y se compilan automáticamente en la configuración subyacente de acceso a datos.
Antes de empezar
- Comprender la diferencia entre la autenticación (quién es) y la autorización (lo que puede hacer)
- Consulte Configuración de la autenticación para configurar la comprobación de identidad
- Comprenda la descripción general de los modelos de datos para conocer los conceptos básicos de las entidades
Roles integrados
Fabric Apps reconoce el rol integrado authenticated. También puede definir roles personalizados en las directivas cuando sea necesario.
| Función | Descripción | Caso de uso |
|---|---|---|
authenticated |
Requiere una sesión de usuario válida con autenticación de Fabric | Datos específicos del usuario, recursos protegidos |
El @role decorador
Aplique @role a nivel de clase para controlar qué roles pueden realizar qué acciones sobre una entidad:
@role(roleName, actions, options?)
Parámetros
| Parámetro | Tipo | Descripción |
|---|---|---|
roleName |
string |
El nombre del rol, como 'authenticated' o un rol de aplicación personalizado |
actions |
string \| string[] |
Acción única o matriz: 'create', 'read', 'update', 'delete'o '*' para todos |
options |
object |
Objeto opcional con propiedades check, include y exclude |
Ejemplo básico
Restringir los usuarios autenticados a sus propios datos:
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;
}
En este ejemplo:
- Los usuarios autenticados solo pueden acceder a los elementos Todo cuyo
userIdcoincide con su declaraciónsubdel JWT.
Expresiones de directiva con tipado seguro
La policy función de devolución de llamada proporciona acceso tipado tanto a las declaraciones como a los campos de entidad. TypeScript infiere el tipo de entidad a partir de la clase decorada, lo que te ofrece autocompletado y seguridad al refactorizar:
policy: (claims, item) => claims.sub.eq(item.userId)
Declaraciones compatibles
| Reclamación | Descripción | Ejemplo de valor |
|---|---|---|
claims.sub |
Identificador del firmante (identificador de usuario) | 00000000-0000-0000-0000-000000000001 |
claims.email |
Dirección de correo electrónico del usuario | user@contoso.com |
claims.role |
Rol de usuario (si lo proporciona el proveedor de identidades) | admin |
Operadores de expresión
| Operador | Ejemplo | Descripción |
|---|---|---|
.eq() |
claims.sub.eq(item.userId) |
Comprobación de igualdad |
Operadores logicos
Combinar expresiones con .and() y .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 lados se ponen automáticamente entre paréntesis para una agrupación correcta.
Permisos de nivel de campo
Especifique los campos a los que puede acceder un rol mediante include o exclude en las opciones de rol.
Incluir campos específicos
Permitir solo el title campo durante las operaciones de creación:
@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 confidenciales de las operaciones de lectura:
@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
Los arrays de campos están tipados con los nombres de propiedad reales de la entidad. Cambiar el nombre de un campo produce un error en tiempo de compilación en cada lista include o exclude que hace referencia a él.
Permisos específicos por acción
Aplique reglas diferentes por acción mediante varios @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 configuración:
-
Crear: solo el creador puede crear y solo se permiten los campos
titleycontent. - Lectura: Solo el creador puede leer sus propios documentos.
-
Actualización: solo el creador puede actualizar, pero no puede modificar
adminNotes. - Eliminar: solo el creador puede eliminar.
Funcionamiento de los permisos
-
Colección de metadatos: el
@roledecorador recopila metadatos de permisos cuando se define la clase . -
Generación de esquemas: al ejecutar
db apply, la CLI lee los metadatos y genera la configuración de permisos. -
Compilación de políticas: las funciones callback de políticas de TypeScript se compilan en expresiones de política de acceso a datos (por ejemplo,
@claims.sub eq @item.userId). - Cumplimiento en tiempo de ejecución: la capa de acceso a datos exige permisos en cada solicitud de API.
-
Detección de conflictos: Los varios decoradores
@rolede una misma clase se agrupan según el rol, con advertencias sobre declaraciones conflictivas.
Patrones comunes
Acceso solo para el propietario
@entity()
@role('authenticated', '*', {
policy: (claims, item) => claims.sub.eq(item.ownerId)
})
export class PrivateNote {
@uuid() id!: string;
@text() ownerId!: string;
@text() content!: string;
}
Acceso total para usuarios autenticados
@entity()
@role('authenticated', '*')
export class BlogPost {
@uuid() id!: string;
@text() title!: string;
@text() content!: string;
}
Anulación del 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;
}
Los administradores pueden modificar cualquier recurso, pero solo los administradores pueden eliminar.
Pasos siguientes
- Configuración de la autenticación para configurar proveedores de identidades
- Consulta de datos con GraphQL para probar consultas protegidas con permisos
- Referencia de comandos de la CLI para comandos de generación de esquemas