เซสชันและความปลอดภัย

เซสชันของเอกสารและการควบคุมการเข้าถึง

โทเคนของ Doconut มีพลังมาก: ผู้ใดที่นำเสนอโทเคนนี้สามารถร้องขอทุกหน้าของเอกสารได้ หากไม่ได้ผูกกับเซสชันที่เปิดเอกสาร หน้านี้อธิบายว่าเซสชันเก็บอะไรไว้, อายุการใช้งานเท่าใด, และการตรวจสอบที่ UseDoconut() เปิดใช้งานโดยค่าเริ่มต้น

สิ่งที่เซสชันของเอกสารเก็บไว้

แต่ละการเรียก OpenDocumentAsync ที่สำเร็จจะสร้างเซสชันหนึ่งใน IMemoryCache:

  • loaded format viewer – อินสแตนซ์เอนจินเอกสารที่ถือเอกสารที่แปลงแล้ว,
  • per-page state – การหมุน, การพลิก, และข้อมูลคำอธิบายที่ผู้ใช้ใส่ในวิดเจ็ต,
  • search index (ตัวเลือก) – สร้างแบบ lazy ครั้งแรกที่ทำการค้นหา (หรือโหลดจากไฟล์ .srh ที่สร้างล่วงหน้าในสถานการณ์เว็บฟาร์ม),
  • watermark ของเซสชันจาก DocOptions.Watermark.

อายุการใช้งาน

เซสชันหมดอายุตาม sliding window: DocOptions.TimeOut นาที (ค่าเริ่มต้น 60) และจะรีเซ็ตทุกครั้งที่มีคำขอที่นำเสนอโทเคน เมื่อเซสชันถูกไล่ออก — ไม่ว่าจะโดยการหมดอายุหรือโดย CloseDocument(token) — คอลแบ็กการไล่ออกจะทำลายเอนจินเอกสารและคืนหน่วยความจำที่เกี่ยวข้องทันที

csharp
// เซสชันที่มีอายุสั้นสำหรับการพรีวิวแบบครั้งเดียว
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });

คำขอที่ใช้โทเคนที่หมดอายุจะได้รับภาพข้อผิดพลาดที่เขียนว่า Document session not found. Please re-open document. — ลูกค้าต้องเปิดเอกสารใหม่เพื่อรับโทเคนใหม่

การผูกโทเคนในตัว

เมื่อ UnsafeMode = false (ค่าเริ่มต้น) OpenDocumentAsync จะผูกโทเคนใหม่กับ ASP.NET session ของคำขอ HTTP ที่เปิดเอกสารนั้นโดยเขียนมาร์กเกอร์ secure-{token} ลงในเซสชันนั้นเอง มิดเดิลแวร์ของ Doconut จะปฏิเสธการให้บริการหน้าใด ๆ กับเซสชันเบราว์เซอร์อื่น:

  • เบราว์เซอร์/เซสชันที่ต่างกันนำเสนอโทเคนที่ถูกขโมย → ภาพข้อผิดพลาด You Are Not Authorized To View This Page.
  • มิดเดิลแวร์เซสชันไม่ได้ลงทะเบียน → HTTP 500 Session middleware not configured. Call UseSession() before UseDoconut().

นี่คือเหตุผลที่ Quick Start บังคับให้ใช้ AddSession() + app.UseSession() ก่อนสาขา Doconut ผลลัพธ์เชิงปฏิบัติสองประการ:

  • ลูกค้าต้องส่ง session cookie ของ ASP.NET ไปพร้อมกับคำขอหน้า การตั้งค่า cross‑origin ที่ลบคุกกี้ (หรือไคลเอนต์ API ที่ไม่มีคุกกี้) จะทำให้การตรวจสอบล้มเหลว — นั่นคือฟีเจอร์ทำงาน, ไม่ใช่บั๊ก
  • options.UnsafeMode = true ปิดการผูกโทเคนทั้งหมด ใช้สำหรับสถานการณ์ที่ควบคุมได้ (เช่น การเรนเดอร์ server‑to‑server) ควรตั้งเป็น false ในการผลิต

การผูกโทเคนถูกควบคุมโดยสวิตช์ระดับโลก UnsafeMode เพียงอย่างเดียว — เปิดโดยค่าเริ่มต้น (UnsafeMode = false) และใช้กับทุกเซสชัน ไม่มีการยกเว้นระดับเอกสาร; การตั้งค่า UnsafeMode = true จะปิดการผูกโทเคนทั่วทั้งระบบ

การให้สิทธิ์การเข้าถึงและผู้ใช้ที่ผ่านการยืนยันตัวตน

เมื่อ UnsafeMode เป็น false UseDoconut() จะใส่ DocumentAccessMiddleware เข้าไปโดยอัตโนมัติก่อนมิดเดิลแวร์ของหน้า อย่าลงทะเบียนซ้ำ เมื่อคำขอมีโทเคน มิดเดิลแวร์จะค้นหา access grant ที่บันทึกไว้เมื่อตอนเปิดเอกสารและจะอนุญาตก็ต่อเมื่อเงื่อนไขต่อไปนี้ทั้งหมดเป็นจริง:

  1. มี grant สำหรับโทเคนนั้นอยู่,
  2. ยังไม่หมดอายุ (อายุของ grant เท่ากับ TimeOut ของเอกสาร),
  3. ID ของ ASP.NET session ที่ร้องขอเท่ากับ ID ของเซสชันที่เปิดเอกสาร,
  4. หากผู้เปิดเอกสารผ่านการยืนยันตัวตน claim NameIdentifier ของผู้ร้องขอก็ต้องตรงกันด้วย

หากตรวจสอบไม่ผ่านจะคืนค่า 403 — เป็นภาพ PNG ข้อผิดพลาดสำหรับคำขอหน้า/thumbnail, หรือเป็นข้อความธรรมดาสำหรับกรณีอื่น ๆ ข้อความและคีย์ query ของโทเคนมาจาก DocumentSecurityOptions (TokenQueryKey ค่าเริ่มต้น "token"; UnauthorizedMessage ค่าเริ่มต้น "You Are Not Authorized To View This Page.") ตั้งค่าตัวเลือกเหล่านี้ผ่าน DI ของ ASP.NET Core ก่อนสร้างแอป หากสถานะเซสชันไม่พร้อมใช้งาน มิดเดิลแวร์จะปิดการทำงานด้วย 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.";
});

มิดเดิลแวร์หลักของหน้า จะตรวจสอบมาร์กเกอร์ secure-{token} ของเซสชันก่อนให้บริการเอกสาร หากตั้งค่า UnsafeMode = true UseDoconut() จะข้ามมิดเดิลแวร์การเข้าถึงและการตรวจสอบมาร์กเกอร์หลักก็จะถูกปิดด้วยเช่นกัน

การเพิกถอน

CloseDocument(token) ไม่ได้เพียงแค่คืนหน่วยความจำ — มันยังลบมาร์กเกอร์ secure-{token} และเพิกถอน access grant ด้วย ดังนั้นโทเคนที่ถูกปิดจะเสียชีวิตบนชั้นความปลอดภัยทั้งสองทันที

รายการตรวจสอบสำหรับการผลิต

  • รักษา UnsafeMode = false (ค่าเริ่มต้น) — สวิตช์ระดับโลกนี้เป็นตัวผูกโทเคนกับเซสชัน
  • ลงทะเบียน AddDistributedMemoryCache() (แอป MVC และ Razor Pages มีอยู่แล้ว) และ AddSession() แล้วเรียก app.UseSession() ก่อนสาขามิดเดิลแวร์ของ Doconut
  • ตรวจสอบให้แน่ใจว่า policy ของคุกกี้เซสชันของคุณอนุญาตให้วิดเจ็ตส่งคุกกี้ไปพร้อมกับคำขอ (SameSite, HTTPS)
  • ใช้ CloseDocument เมื่อผู้ใช้ออกจากเอกสาร — ทั้งหน่วยความจำและความปลอดภัยจะได้ประโยชน์
  • อย่าเก็บบันทึกหรือแชร์โทเคน; ปฏิบัติเช่นเป็นข้อมูลประจำตัวที่มีอายุสั้น

หน้านี้เป็นประโยชน์หรือไม่?