Sessioner & Säkerhet
Dokumentsessioner och åtkomstkontroll
En Doconut-token identifierar ett öppet dokument. Om någon begäran som bär den serveras, kan den som erhåller den läsa varje sida. Den här sidan förklarar vad en dokumentsession innehåller, hur länge den lever, och hur DocImage.axd bestämmer vem som får se dess sidor — på en server och i en webbfarm.
Vad en dokumentsession innehåller
Varje lyckad OpenDocumentAsync skapar en session, lagrad i minnet:
- den laddade formatvisaren — motorinstansen som håller det parsade dokumentet,
- per-sidigt tillstånd — rotation, vändningar och annoteringsdata som användaren applicerar i widgeten,
- det valfria sökindexet, byggt vid den första sökningen (eller laddat från en förbyggd
.srh-fil), - sessionens vattenstämpel från
DocOptions.Watermark.
Livstid
Sessioner löper ut på ett glidande fönster: DocOptions.TimeOut minuter (standard 60), återställs av varje begäran som presenterar token. När en session avslutas — genom utgång eller genom CloseDocument(token) — släpps dess dokumentmotor och dess minne frigörs omedelbart.
// En kortlivad session för en engångsförhandsgranskning
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });En begäran med en utgången token får en felbild med texten Document session not found. Please re-open document.. Sidan måste öppna dokumentet igen för att få en ny token. På en enskild server avslutar återvinning av applikationspoolen varje session också.
Sidor levereras endast till den session som öppnade dem
Med UnsafeMode = false — standardvärdet — ger öppning av ett dokument åtkomst till ASP.NET-sessionen för den begäran som öppnade den, genom att skriva en secure-{token}-post i den sessionen. DocImage.axd kräver själva sessionsstatusen, och levererar en sida endast när den begärande sessionen har den posten. Alla andra webbläsare som presenterar samma token får en felbild med texten You Are Not Authorized To View This Page.
Doconut.DoconutHost.Initialize(options =>
{
// false (standardvärdet): DocImage.axd levererar en sida endast till den ASP.NET-session som öppnade den
// dokumentet. Handlaren begär session state själv; den behöver bara att webbplatsen inte
// stänga av session state i Web.config.
options.UnsafeMode = false;
});Tre praktiska konsekvenser:
- Den öppna slutpunkten behöver sessionsstatus. MVC‑kontrollers och Web Forms‑sidor har den som standard. En anpassad
IHttpHandlerhar den inte om den inte implementerarSystem.Web.SessionState.IRequiresSessionState. En öppning som körs utan en session har inget att bevilja, så visaren visar "You Are Not Authorized To View This Page." på varje sida. - Sessionsstatus måste vara på.
<sessionState mode="Off" />iWeb.configinaktiverar både beviljandet och kontrollen, och varje sida avvisas. - Webbläsaren måste skicka sessionskakan. Widgetens begäranden är samma ursprung, så de bär
ASP.NET_SessionIdautomatiskt. En klient utan en cookie‑burk — ett skript, ett server‑till‑server‑anrop, en cross‑origin‑uppsättning som tar bort cookies — avvisas. Det är funktionen som fungerar.
UnsafeMode = true stänger av kontrollen: varje begäran som bär tokenen levereras. Det är en global omkopplare för varje dokument, utan per‑dokument‑överskrivning. Lämna den false.
Återkallelse
CloseDocument(token) gör mer än att frigöra minne: den tar bort secure-{token}-posten från den aktuella begärans session och återkallar tokenen, så en stängd token avvisas omedelbart.
Webbfarmer: signerade biljetter
I en farm kan nästa begäran hamna på en server som aldrig har sett dokumentet, i en annan arbetsprocess, med sin egen ASP.NET-session. Sessionsbeviljandet kan inte följa den. Distribuerat läge ersätter det med en signerad biljett bunden till webbläsaren: varje nod delar en lagring för dokumentsessioner och en signeringsnyckel, och DocImage.axd accepterar en begäran när dess biljett är giltig för den token, den webbläsaren, och — när användaren är inloggad — den användaren.
Inställningen, identisk på varje nod:
// Global.asax.cs - Application_Start
Doconut.DoconutHost.Initialize(
options => options.UnsafeMode = false, // biljettkontrollen körs endast när detta är false
services => services.AddDoconutDistributed(d =>
{
d.Store = CloudLocation.FileShare;
d.FileShareRootPath = @"\\fileserver\doconut-shared"; // en mapp som varje nod kan nå
d.SigningKey = farmKey; // minst 32 byte, SAME på varje nod
}));Den öppna slutpunkten binder sedan biljetten till webbläsaren innan öppning, och returnerar biljetten med tokenen:
- sätt
DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(System.Web.HttpContext.Current, securityOptions)— den utfärdardoconut-client-kakan som biljetten är knuten till — ochDocOptions.UserId = DoconutFarmBinding.ResolveUserId(System.Web.HttpContext.Current); - efter
OpenDocumentAsync, returneraviewer.AccessTokentillsammans med tokenen; - i sidan, skicka båda till widgeten:
objViewer.View(token, access).
Doconut.MvcSample.WebFarm i exempelpaketet är en komplett, körbar farmnod, och migrationsguiden bredvid förklarar varje steg.
Behåll signeringsnyckeln utanför källkodshantering: den både signerar biljetterna och krypterar dokumenten i den delade lagringen. En nod med en annan nyckel avvisar varje biljett som de andra utfärdat.
Testa en farm med en riktig webbläsare, eller ett skript som behåller cookies. En klient utan doconut-client-kakan svaras inte med 401: den får felbilden "not authorized" med status 200, cirka 2 KB, där en riktig sida är tiotals till hundratals kilobyte.
Produktionschecklista
- Behåll
UnsafeMode = false(standardvärdet). - Öppna dokument från begäranden som har sessionsstatus, och stäng aldrig av sessionsstatus.
- Se till att sessionskakan når
DocImage.axd(samma ursprung, HTTPS, enSameSite-policy som tillåter det). - I en farm, använd distribuerat läge med en signeringsnyckel delad av varje nod.
- Anropa
CloseDocumentnär användaren lämnar ett dokument — minne och säkerhet gynnas båda. - Logga eller dela aldrig tokens; behandla dem som kortlivade autentiseringsuppgifter.
Var den här sidan hjälpsam?