Sesiones y Seguridad

Sesiones de documentos y control de acceso

Un token de Doconut es poderoso: quien lo presente podría solicitar cada página del documento si no estuviera vinculado a la sesión de apertura. Esta página explica qué contiene una sesión, cuánto tiempo dura y las verificaciones que UseDoconut() habilita por defecto.

Qué contiene una sesión de documento

Cada OpenDocumentAsync exitoso crea una sesión en IMemoryCache:

  • el visor de formato cargado (la instancia del motor de documento que contiene el documento analizado),
  • estado por página — rotación, volteos y datos de anotación que el usuario aplica en el widget,
  • el índice de búsqueda opcional, construido perezosamente en la primera búsqueda (o cargado desde un archivo .srh preconstruido en escenarios de granja web),
  • la marca de agua de la sesión proveniente de DocOptions.Watermark.

Tiempo de vida

Las sesiones expiran en una ventana deslizante: DocOptions.TimeOut minutos (por defecto 60), reiniciada por cada solicitud que presente el token. Cuando una sesión es expulsada — por expiración o por CloseDocument(token) — su callback de expulsión elimina el motor de documento y libera la memoria asociada inmediatamente.

csharp
// A short-lived session for a one-shot preview
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });

Una solicitud con un token expirado recibe una imagen de error que muestra Document session not found. Please re-open document. — el cliente debe volver a abrir el documento para obtener un token nuevo.

Vinculación de token incorporada

Con UnsafeMode = false (el valor predeterminado), OpenDocumentAsync vincula el nuevo token a la sesión ASP.NET de la solicitud HTTP que lo abrió, escribiendo un marcador secure-{token} en esa sesión. El middleware de Doconut entonces se niega a servir páginas a cualquier otra sesión de navegador:

  • Navegador/sesión diferente que presenta un token robado → imagen de error You Are Not Authorized To View This Page.
  • Middleware de sesión no registrado → HTTP 500 Session middleware not configured. Call UseSession() before UseDoconut().

Por eso el Quick Start insiste en AddSession() + app.UseSession() antes de la rama de Doconut. Dos consecuencias prácticas:

  • El cliente debe enviar la cookie de sesión de ASP.NET con las solicitudes de página. Configuraciones de origen cruzado que eliminan cookies (o un cliente API sin almacén de cookies) fallarán la verificación — eso es la característica funcionando, no un error.
  • options.UnsafeMode = true desactiva la vinculación por completo. Existe para escenarios controlados (p. ej., renderizado servidor a servidor); déjelo false en producción.

La vinculación de token se controla únicamente mediante este interruptor global UnsafeMode — está activado por defecto (UnsafeMode = false) y se aplica a todas las sesiones. No hay exclusión por documento; establecer UnsafeMode = true desactiva la vinculación globalmente.

Concesiones de acceso y usuarios autenticados

Cuando UnsafeMode es false, UseDoconut() inserta DocumentAccessMiddleware automáticamente antes del middleware de página. No lo registre una segunda vez. Cuando una solicitud lleva un token, busca la concesión de acceso registrada cuando se abrió el documento y autoriza solo si se cumplen todos los siguientes requisitos:

  1. existe una concesión para el token,
  2. no ha expirado (la vida útil de la concesión = el TimeOut del documento),
  3. el ID de sesión ASP.NET de la solicitud coincide con el que abrió el documento,
  4. si el que abrió estaba autenticado, la reclamación NameIdentifier del usuario solicitante también coincide.

Los fallos devuelven 403 — como una imagen PNG de error para solicitudes de página/miniatura, y como texto plano en otros casos. El mensaje y la clave de consulta del token provienen de DocumentSecurityOptions (TokenQueryKey, por defecto "token"; UnauthorizedMessage, por defecto "You Are Not Authorized To View This Page."). Configure esas opciones mediante la inyección de dependencias de ASP.NET Core antes de construir la aplicación. Si el estado de sesión no está disponible, el middleware falla cerrado con HTTP 500: ASP.NET Session is required for Doconut document security.

csharp
builder.Services.Configure<Doconut.Security.DocumentSecurityOptions>(options =>
{
    options.TokenQueryKey = "token";
    options.UnauthorizedMessage = "You Are Not Authorized To View This Page.";
});

El middleware central de página verifica entonces el marcador de sesión secure-{token} antes de servir el documento. Con UnsafeMode = true, UseDoconut() omite el middleware de acceso y la verificación del marcador central también se desactiva.

Revocación

CloseDocument(token) no solo libera memoria — también elimina el marcador secure-{token} y revoca la concesión de acceso, de modo que un token cerrado queda inactivo en ambas capas de seguridad inmediatamente.

Lista de verificación para producción

  • Mantenga UnsafeMode = false (el valor predeterminado) — este interruptor global es lo que vincula los tokens a las sesiones.
  • Registre AddSession() y llame a app.UseSession() antes de la rama del middleware de Doconut.
  • Asegúrese de que la política de cookies de sesión permita que las solicitudes del widget lleven la cookie (SameSite, HTTPS).
  • Utilice CloseDocument cuando el usuario abandone el documento — la memoria y la seguridad se benefician.
  • Nunca registre ni comparta tokens; trátelos como credenciales de corta duración.

¿Fue útil esta página?