Sessioni e Sicurezza
Sessioni dei documenti e controllo degli accessi
Un token Doconut identifica un documento aperto. Se qualsiasi richiesta che lo trasporta fosse servita, chi lo avesse ottenuto potrebbe leggere ogni pagina. Questa pagina spiega cosa contiene una sessione di documento, per quanto tempo dura e come DocImage.axd decide chi può vedere le sue pagine — su un singolo server e in un web farm.
Cosa contiene una sessione di documento
Ogni chiamata riuscita a OpenDocumentAsync crea una sessione, mantenuta in memoria:
- il visualizzatore di formato caricato — l'istanza del motore che contiene il documento analizzato,
- stato per pagina — rotazione, capovolgimenti e i dati di annotazione che l'utente applica nel widget,
- l'indice di ricerca opzionale, costruito alla prima ricerca (o caricato da un file
.srhpre‑costruito), - il watermark della sessione da
DocOptions.Watermark.
Durata
Le sessioni scadono su una finestra mobile: DocOptions.TimeOut minuti (default 60), resettata da ogni richiesta che presenta il token. Quando una sessione termina — per scadenza o tramite CloseDocument(token) — il suo motore di documento viene rilasciato e la memoria liberata immediatamente.
// A short-lived session for a one-shot preview
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });Una richiesta con un token scaduto restituisce un'immagine di errore con il testo Document session not found. Please re-open document. La pagina deve riaprire il documento per ottenere un nuovo token. Su un singolo server, il riciclo del pool di applicazioni termina anche tutte le sessioni.
Le pagine sono servite solo alla sessione che le ha aperte
Con UnsafeMode = false — il valore predefinito — l'apertura di un documento concede l'accesso alla sessione ASP.NET della richiesta che lo ha aperto, scrivendo una voce secure-{token} in quella sessione. DocImage.axd richiede lo stato della sessione stesso e serve una pagina solo quando la sessione richiedente contiene tale voce. Qualsiasi altro browser che presenta lo stesso token ottiene un'immagine di errore con il testo You Are Not Authorized To View This Page.
Doconut.DoconutHost.Initialize(options =>
{
// false (the default): DocImage.axd serves a page only to the ASP.NET session that opened
// the document. The handler asks for session state itself; it only needs the site not to
// turn session state off in Web.config.
options.UnsafeMode = false;
});Tre conseguenze pratiche:
- L'endpoint di apertura necessita dello stato di sessione. I controller MVC e le pagine Web Forms lo hanno per impostazione predefinita. Un
IHttpHandlerpersonalizzato non lo ha a meno che non implementiSystem.Web.SessionState.IRequiresSessionState. Un'apertura che viene eseguita senza una sessione non ha nulla da concedere, quindi il visualizzatore mostra "You Are Not Authorized To View This Page." su ogni pagina. - Lo stato di sessione deve rimanere attivo.
<sessionState mode="Off" />inWeb.configdisabilita sia la concessione che il controllo, e ogni pagina viene rifiutata. - Il browser deve inviare il cookie di sessione. Le richieste del widget sono same-origin, quindi trasportano automaticamente
ASP.NET_SessionId. Un client senza contenitore di cookie — uno script, una chiamata server‑to‑server, una configurazione cross‑origin che rimuove i cookie — viene rifiutato. Questa è la funzionalità in azione.
UnsafeMode = true disattiva il controllo: qualsiasi richiesta che trasporta il token viene servita. È un interruttore globale per tutti i documenti, senza possibilità di sovrascrivere per documento. Lasciare impostato a false.
Revoca
CloseDocument(token) fa più che liberare memoria: rimuove la voce secure-{token} dalla sessione della richiesta corrente e revoca il token, così un token chiuso viene rifiutato immediatamente.
Web farm: ticket firmati
In un farm, la richiesta successiva può arrivare su un server che non ha mai visto il documento, in un processo worker diverso, con la propria sessione ASP.NET. Il permesso di sessione non può seguirla. La modalità distribuita lo sostituisce con un ticket firmato legato al browser: ogni nodo condivide un unico archivio per le sessioni dei documenti e una chiave di firma, e DocImage.axd accetta una richiesta quando il suo ticket è valido per quel token, quel browser e — quando l'utente è autenticato — quell'utente.
La configurazione, identica su ogni nodo:
// Global.asax.cs - Application_Start
Doconut.DoconutHost.Initialize(
options => options.UnsafeMode = false, // the ticket check only runs when this is false
services => services.AddDoconutDistributed(d =>
{
d.Store = CloudLocation.FileShare;
d.FileShareRootPath = @"\\fileserver\doconut-shared"; // a folder every node can reach
d.SigningKey = farmKey; // at least 32 bytes, the SAME on every node
}));L'endpoint di apertura quindi associa il ticket al browser prima dell'apertura, e restituisce il ticket insieme al token:
- imposta
DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(System.Web.HttpContext.Current, securityOptions)— genera il cookiedoconut-clienta cui è legato il ticket — eDocOptions.UserId = DoconutFarmBinding.ResolveUserId(System.Web.HttpContext.Current); - dopo
OpenDocumentAsync, restituisciviewer.AccessTokeninsieme al token; - nella pagina, passa entrambi al widget:
objViewer.View(token, access).
Doconut.MvcSample.WebFarm nel pacchetto di esempi è un nodo farm completo e eseguibile, e la guida di migrazione accanto spiega ogni passaggio.
Mantieni la chiave di firma fuori dal controllo del codice sorgente: firma sia i ticket sia i documenti nello store condiviso. Un nodo con una chiave diversa rifiuta tutti i ticket emessi dagli altri.
Testa un farm con un browser reale, o con uno script che conserva i cookie. Un client senza il cookie doconut-client non riceve un 401: ottiene l'immagine di errore "not authorized" con stato 200, circa 2 KB, dove una pagina reale è di decine o centinaia di kilobyte.
Checklist di produzione
- Mantieni
UnsafeMode = false(il valore predefinito). - Apri i documenti da richieste che hanno lo stato di sessione, e non disattivare mai lo stato di sessione.
- Assicurati che il cookie di sessione raggiunga
DocImage.axd(same origin, HTTPS, una politicaSameSiteche lo consenta). - In un farm, utilizza la modalità distribuita con una chiave di firma condivisa da tutti i nodi.
- Chiama
CloseDocumentquando l'utente abbandona un documento — la memoria e la sicurezza ne traggono beneficio. - Non registrare né condividere i token; trattali come credenziali a breve durata.
Questa pagina è stata utile?