Sesiones y Seguridad
Sesiones de documentos y control de acceso
Un token 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 documentos 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
.srhpreconstruido cuando las páginas se sirven desde almacenamiento compartido), - la marca de agua de la sesión de
DocOptions.Watermark.
Tiempo de vida
Las sesiones expiran en una ventana deslizante: DocOptions.TimeOut minutos (predeterminado 60), reiniciada por cada solicitud que presente el token. Cuando una sesión es expulsada — por expiración o por CloseDocument(token) — su devolución de llamada de expulsión elimina el motor de documentos y libera la memoria asociada inmediatamente.
// Una sesión de corta duración para una vista previa única
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 para obtener un token nuevo.
Vinculación de token incorporada
Con UnsafeMode = false (el 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 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 Inicio Rápido insiste en AddSession() + app.UseSession() antes de la rama Doconut. Dos consecuencias prácticas:
- El cliente debe enviar la cookie de sesión 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 funcionalidad trabajando, no un error.
options.UnsafeMode = truedesactiva la vinculación por completo. Existe para escenarios controlados; déjelofalseen producción en un solo nodo.
Observe la ortografía. La biblioteca .NET Standard anterior llamaba a esta propiedad UnSafeMode
y se pasaba al middleware; aquí es UnsafeMode y se establece una sola vez dentro de
AddDoconut().
La vinculación de tokens se controla únicamente mediante este interruptor global UnsafeMode — está activado por defecto (UnsafeMode = false) y se aplica a cada sesión. No hay exclusión por documento; establecer UnsafeMode = true desactiva la vinculación globalmente.
Concesiones de acceso y usuarios autenticados
Cuando UnsafeMode está false, UseDoconut() inserta automáticamente el middleware de acceso a documentos 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 todas estas condiciones:
- existe una concesión para el token,
- no ha expirado (tiempo de vida de la concesión = el
TimeOutdel documento), - el ID de sesión ASP.NET solicitante coincide con el que abrió el documento,
- si el iniciador estaba autenticado, la reclamación
NameIdentifierdel 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, predeterminado "token"; UnauthorizedMessage, predeterminado "You Are Not Authorized To View This Page."). Configure esas opciones mediante ASP.NET Core DI 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.
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 luego verifica 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 está desactivada.
Seguridad en varios nodos
Los tokens vinculados a la sesión asumen que el nodo que sirve una página también vio la solicitud que abrió el documento. Esa suposición no se cumple cuando varios nodos sirven los mismos documentos desde almacenamiento compartido: una solicitud de página puede llegar a un nodo que nunca vio la apertura, y la verificación por sesión lo rechaza.
La solución no es dejar los documentos sin protección. Use tickets de acceso firmados a través de
AddDoconutDistributedDocumentSecurity(...), que reemplaza la verificación de sesión con una
credencial que cada nodo puede verificar de forma independiente. La configuración completa está en
Despliegues Distribuidos.
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 predeterminado) en un solo nodo — este interruptor global es lo que vincula los tokens a las sesiones. - Registre
AddDistributedMemoryCache()(las aplicaciones MVC y Razor Pages ya lo tienen) yAddSession(), y llame aapp.UseSession()antes de la rama del middleware Doconut. - Asegúrese de que la política de cookies de sesión permita que las solicitudes del widget lleven la cookie (
SameSite, HTTPS). - Use
CloseDocumentcuando 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.
- ¿Sirviendo desde almacenamiento compartido? Cambie a tickets de acceso firmados en lugar de aceptar documentos sin protección.
¿Fue útil esta página?