Suplantación de usuario
Algunos fallos solo existen para una persona. Un registro que no se abre, un elemento de menú que no está, un total que parece incorrecto — todo depende de los roles web, permisos de tabla y roles de seguridad de Dataverse asociados a ese contacto. La suplantación de usuario permite a un administrador interno iniciar sesión como ese contacto y ver exactamente qué ve, para luego salir de nuevo.
Cuando ayuda
La suplantación responde a preguntas que una descripción del problema no puede.
- Reproduciendo un problema de soporte. En lugar de razonar qué permiso podría faltar, miras la página como lo hace la persona que lo denuncia.
- Verificando un cambio de permiso. Después de editar un permiso web role o una tabla, confirma el efecto sobre un contacto real en lugar de inferirlo.
- Comprobar qué expone realmente un puesto. Útil antes de la puesta en marcha, cuando la diferencia entre el acceso previsto y el acceso real es más fácil de equivocar.
Usándolo
La posibilidad está en el menú de perfil y solo aparece para los usuarios autorizados a usarla.
- Inicia sesión como usuario interno con el rol de administrador, luego abre el menú del perfil y elige Ver como otro usuario.
- Escribe al menos tres caracteres para buscar por nombre o dirección de correo electrónico, o pega un ID de usuario para obtener una coincidencia exacta.
- Elige a la persona y confirma. El portal se recarga como ellos — mismos roles web, mismos permisos de tabla, mismas filas.
- Un banner permanece fijado en la parte superior de cada página mientras dure. Elige Detener para volver a tu propia sesión.
Que puede suplantar
Se comprueban dos condiciones en el servidor para cada llamada, independientemente de lo que ofrezca la interfaz:
- El usuario iniciado sesión ocupa el
SystemAdminrol. Tu proyecto decide qué rol de seguridad de Dataverse lo otorga — las plantillas generadas mapean el rol integrado de Administrador de Sistemas más uno configurable a través dePortalIdentityOptions.SystemAdminRoleName. - El usuario iniciado sesión es un usuario interno genuino de Dataverse. Esto se comprueba por separado del puesto, por lo que un contacto del portal nunca puede suplantar el puesto aunque tu proyecto le conceda el puesto por error.
El objetivo siempre es un contacto del portal, resuelto solo a través de la tabla de contactos. Proporcionar el ID de otro usuario interno simplemente no resuelve — no hay camino desde aquí hasta una segunda cuenta de personal.
La suplantación solo reduce el acceso
Un usuario interno se convierte en contacto, nunca al revés ni otro usuario interno. Esa dirección es lo que mantiene la función segura para el envío: la sesión suplantada solo puede hacer menos de lo que el administrador podría hacer, así que no hay privilegio que ganar usándola.
Restringir quién puede ser suplantado
Por defecto, todo contacto activo es un candidato. Implementa IImpersonationTargetFilter para restringir eso — excluye contactos vinculados a cuentas de personal, registros fuera de la unidad de negocio del administrador o cualquier otra cosa que tu organización trate como prohibido.
public sealed class StaffContactsAreOffLimits : IImpersonationTargetFilter
{
public async Task<bool> CanImpersonateAsync(
ClaimsPrincipal impersonator, Guid targetContactId, CancellationToken ct)
{
// Return false to hide the contact from search AND refuse impersonation.
return await this.IsOrdinaryPortalContactAsync(targetContactId, ct);
}
}
// Program.cs
builder.Services.AddScoped<IImpersonationTargetFilter, StaffContactsAreOffLimits>();
El filtro regula la búsqueda y la suplantación. Un contacto que rechazas es invisible en el selector en lugar de simplemente no seleccionable — de lo contrario, la búsqueda se convertiría silenciosamente en una forma de enumerar personas que un administrador nunca podría llegar a ser.
La pista de auditoría
Se registra cada intento de salida, parada y rechazo. Las negativas se registran deliberadamente: una sola serie de éxitos no puede responder si alguien lo intentó.
Dataverse no puede registrar quién estaba detrás de la sesión
El portal se conecta a Dataverse como un único usuario de aplicación y expresa la sesión iniciada suplantando al destino. El administrador nunca se transmite, por lo que en el registro de auditoría de Dataverse "un administrador actuando como contacto" y "ese contacto iniciando sesión normalmente" son indistinguibles — y cualquier cosa escrita durante la suplantación se atribuye al contacto en
createdbyymodifiedby. La pista del lado del portal es el único lugar donde existe esta información, por lo que no es opcional.
De serie, cada evento se escribe en el registro de la aplicación. Implementa IImpersonationAuditSink que persista donde tu organización guarde sus registros de auditoría: los sumideros se añaden junto al incorporado en lugar de reemplazarlo.
public sealed class ImpersonationAuditTable : IImpersonationAuditSink
{
public Task OnStartedAsync(ImpersonationAuditEvent e, CancellationToken ct) => this.WriteAsync("started", e, ct);
public Task OnStoppedAsync(ImpersonationAuditEvent e, CancellationToken ct) => this.WriteAsync("stopped", e, ct);
// Denied attempts matter as much as successful ones — a trail of
// successes alone can't answer "did anyone try?".
public Task OnDeniedAsync(ImpersonationAuditEvent e, string reason, CancellationToken ct) => this.WriteAsync(reason, e, ct);
}
// Program.cs — added, not replaced: the framework's own logging sink stays.
builder.Services.AddTransient<IImpersonationAuditSink, ImpersonationAuditTable>();
De React
La misma experiencia se utiliza para React: una entrada en el menú de perfil, el selector y el banner. Las acciones subyacentes están activadas useAuth() si prefieres construir tu propia interfaz alrededor de ellas.
const auth = useAuth();
// Search, then start. Both are refused server-side unless the caller
// is an internal user holding the SystemAdmin role.
const { results } = await auth.searchImpersonationTargets('smith');
await auth.impersonate(results[0].contactId);
// While impersonating, `auth.user` describes the CONTACT.
auth.user.isImpersonating; // true
auth.user.impersonatorName; // the administrator behind the session
await auth.stopImpersonation();
Vale la pena saberlo
- Si el contacto suplantado cambia su contraseña a mitad de sesión, la sesión termina y vuelves al estado de cierre en vez de a tu propia cuenta. Iniciar sesión de nuevo lo restaura.
- La suplantación no puede anidarse. Detén la sesión actual antes de empezar otra.
- No dura más que la sesión del navegador: cerrar el navegador la termina.
