Seguridad

PowerPortalsPro ofrece un modelo de seguridad flexible y basado en código que te permite controlar el acceso tanto a nivel de tabla como a nivel de registro. La seguridad se implementa creando clases de manejadores de permisos y registrándolas en el contenedor de inyección de dependencias.

Resumen

Hay dos interfaces que puedes implementar dependiendo del nivel de control que necesites:

Propina

Si solo necesitas comprobaciones a nivel de tabla (por ejemplo, "los usuarios autenticados pueden leer esta tabla"), usa ITablePermissionHandler. Si necesitas lógica a nivel de registro (por ejemplo, "los usuarios solo pueden eliminar registros que poseen"), usa ITableRecordPermissionHandler.

Empezando

1. Crear un gestor de permisos

Crea una clase que implemente ITablePermissionHandler o ITableRecordPermissionHandler. Establece la Table propiedad en el nombre lógico de la tabla Dataverse a la que se aplica el manejador e implementa cada método de permisos.

Aquí tienes un ejemplo sencillo que otorga acceso completo a todos los usuarios para una tabla específica:

2. Registrar en la inyección de dependencias

Registra tu manejador en el contenedor DI del archivo de Program.cs tu proyecto (o en un método de extensión de colección de servicios):

Dado que los manejadores se resuelven desde el contenedor DI, puedes inyectar cualquier servicio requerido (como un contexto de base de datos o un servicio de usuario) mediante inyección de constructores.

Seguridad a nivel de récord

Para escenarios en los que el acceso depende del registro específico en el que se está operando, implementa ITableRecordPermissionHandler. Esta interfaz se extiende ITablePermissionHandler con sobrecargas que reciben el TableRecord.

El siguiente ejemplo permite a todos los usuarios leer registros globalmente, pero restringe las operaciones de escritura a los registros propiedad del usuario actual:

Nota

La CanUpdateAsync sobrecarga a nivel de registro proporciona tanto al registro las actualizaciones propuestas (recordWithUpdates) como al registro en su estado persistido actual (currentRecord), lo que permite comparar valores o validar cambios específicos en el campo.

Columnas requeridas

La RequiredColumns propiedad especifica qué columnas deben recuperarse para que el manejador evalúe permisos a nivel de registro. El framework añade automáticamente estas columnas a las consultas FetchXML cuando no están ya incluidas, asegurando que el gestor siempre tenga los datos que necesita — incluso si la vista o consulta no incluye esas columnas.

El siguiente ejemplo utiliza la ppp_owningportaluserid columna de búsqueda para restringir el acceso a registros propiedad del usuario actual:

Nota

Si RequiredColumns devuelve una lista vacía y los métodos a nivel de registro del manejador solo usan record.Id, no se añaden columnas adicionales a la consulta. La owner propiedad siempre es proporcionada por la plataforma, independientemente de RequiredColumns.

Interceptores de filtro de consulta FetchXML

Además de la seguridad a nivel de tabla y registro, PowerPortalsPro soporta IFetchXmlQueryFilterInterceptor — una interfaz que permite modificar consultas FetchXML antes de que se ejecuten. Esto es útil para hacer cumplir el filtrado a nivel de fila, como asegurar que un usuario solo pueda ver los registros que le pertenecen a él o a su equipo.

IFetchXmlQueryFilterInterceptor extiende ITablePermissionHandler, por lo que cada interceptor también define permisos a nivel de tabla mediante la Table propiedad y los métodos de permisos estándar. El método del OnQueryAsync interceptor solo se llama para consultas que se dirigen a su tabla especificada.

A diferencia de los gestores de permisos a nivel de registro que evalúan cada registro tras la recuperación, los interceptores de filtro de consulta modifican la consulta antes de que llegue a Dataverse. Esto significa que los registros filtrados nunca se recuperan, lo que mejora tanto el rendimiento como la seguridad.

1. Crear un interceptor de filtro de consulta

Implementa IFetchXmlQueryFilterInterceptor, establece la Table propiedad al nombre lógico de la tabla, implementa los métodos de permisos y usa el FetchXMLBuilder in OnQueryAsync para añadir filtros a la consulta. El FetchXmlParameters registro proporciona el archivo del usuario EntityReferenceactual FetchXMLBuilder

El siguiente ejemplo restringe las consultas en la contact tabla para que solo devuelvan el registro que coincide con el usuario actual:

2. Registrar en la inyección de dependencias

Registra tu interceptor tanto como un IFetchXmlQueryFilterInterceptor como ITablePermissionHandler un para que se apliquen tanto el filtrado de consultas como los permisos a nivel de tabla. Se pueden registrar múltiples interceptores y cada uno se ejecutará para consultas dirigidas a su tabla.

Propina

Porque IFetchXmlQueryFilterInterceptor extiende ITablePermissionHandler, una sola clase gestiona tanto permisos a nivel de tabla como filtrado a nivel de consulta. El OnQueryAsync método solo se invoca para consultas que coinciden con la propiedad del Table interceptor, por lo que no es necesario comprobar el nombre de la tabla dentro del método.

Clases base integradas

El marco proporciona clases base para simplificar patrones de seguridad comunes:

Referencia API

ITablePermissionHandler Interface

Propiedades

Nombre
Tipo
Default
Descripción
Tablestring
Nombre lógico de la tabla a la que se aplica este manejador de permisos.
Nombre: Table
Tipo: string
Descripción: Nombre lógico de la tabla a la que se aplica este manejador de permisos.

Métodos

Nombre
Parámetros
Tipo
Descripción
CanAppendAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería poder añadir un registro.
CanAppendToAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe poder añadir a un registro.
CanCreateAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe ser capaz de crear un registro.
CanDeleteAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería poder eliminar un registro.
CanReadAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería ser capaz de leer un registro.
CanUpdateAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe poder actualizar un registro.
Nombre: CanAppendAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería poder añadir un registro.
Nombre: CanAppendToAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder añadir a un registro.
Nombre: CanCreateAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe ser capaz de crear un registro.
Nombre: CanDeleteAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería poder eliminar un registro.
Nombre: CanReadAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería ser capaz de leer un registro.
Nombre: CanUpdateAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder actualizar un registro.

ITableRecordPermissionHandler Interface

Propiedades

Nombre
Tipo
Default
Descripción
RequiredColumnsList<string>
Lista de nombres lógicos de columnas que deben recuperarse para que este manejador pueda evaluar permisos a nivel de registro.
Tablestring
Nombre lógico de la tabla a la que se aplica este manejador de permisos.
Nombre: RequiredColumns
Tipo: List<string>
Descripción: Lista de nombres lógicos de columnas que deben recuperarse para que este manejador pueda evaluar permisos a nivel de registro.
Nombre: Table
Tipo: string
Descripción: Nombre lógico de la tabla a la que se aplica este manejador de permisos.

Métodos

Nombre
Parámetros
Tipo
Descripción
CanAppendAsyncGuid? userId
TableRecord record
Task<bool>
Método para determinar si un usuario debe poder añadir el registro proporcionado.
CanAppendToAsyncGuid? userId
TableRecord record
Task<bool>
Método para determinar si un usuario debe poder añadir al registro proporcionado.
CanCreateAsyncGuid? userId
TableRecord record
Task<bool>
Método para determinar si un usuario debe poder crear el registro proporcionado.
CanDeleteAsyncGuid? userId
TableRecord record
Task<bool>
Método para determinar si un usuario debe poder eliminar el registro proporcionado.
CanReadAsyncGuid? userId
TableRecord record
Task<bool>
Método para determinar si un usuario debe poder leer el registro proporcionado.
CanUpdateAsyncGuid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Task<bool>
Método para determinar si un usuario debe poder actualizar el registro proporcionado.
Nombre: CanAppendAsync
Parámetros: Guid? userId
TableRecord record
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder añadir el registro proporcionado.
Nombre: CanAppendToAsync
Parámetros: Guid? userId
TableRecord record
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder añadir al registro proporcionado.
Nombre: CanCreateAsync
Parámetros: Guid? userId
TableRecord record
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder crear el registro proporcionado.
Nombre: CanDeleteAsync
Parámetros: Guid? userId
TableRecord record
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder eliminar el registro proporcionado.
Nombre: CanReadAsync
Parámetros: Guid? userId
TableRecord record
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder leer el registro proporcionado.
Nombre: CanUpdateAsync
Parámetros: Guid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder actualizar el registro proporcionado.

IFetchXmlQueryFilterInterceptor Interface

Propiedades

Nombre
Tipo
Default
Descripción
Tablestring
Nombre lógico de la tabla a la que se aplica este manejador de permisos.
Nombre: Table
Tipo: string
Descripción: Nombre lógico de la tabla a la que se aplica este manejador de permisos.

Métodos

Nombre
Parámetros
Tipo
Descripción
CanAppendAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería poder añadir un registro.
CanAppendToAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe poder añadir a un registro.
CanCreateAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe ser capaz de crear un registro.
CanDeleteAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería poder eliminar un registro.
CanReadAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debería ser capaz de leer un registro.
CanUpdateAsyncGuid? userId
Task<bool>
Método para determinar si un usuario debe poder actualizar un registro.
OnQueryAsyncFetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Task<FetchXMLBuilder>
Se llama para permitir la modificación de una consulta FetchXML antes de que se ejecute.
Nombre: CanAppendAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería poder añadir un registro.
Nombre: CanAppendToAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder añadir a un registro.
Nombre: CanCreateAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe ser capaz de crear un registro.
Nombre: CanDeleteAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería poder eliminar un registro.
Nombre: CanReadAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debería ser capaz de leer un registro.
Nombre: CanUpdateAsync
Parámetros: Guid? userId
Tipo: Task<bool>
Descripción: Método para determinar si un usuario debe poder actualizar un registro.
Nombre: OnQueryAsync
Parámetros: FetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Tipo: Task<FetchXMLBuilder>
Descripción: Se llama para permitir la modificación de una consulta FetchXML antes de que se ejecute.