Сесії та безпека

Сесії документу та контроль доступу

Токен Doconut є потужним: будь-хто, хто його пред’явить, може запросити кожну сторінку документу, якщо він не прив’язаний до відкритої сесії. Ця сторінка пояснює, що містить сесія, як довго вона живе та які перевірки UseDoconut() вмикає за замовчуванням.

Що містить сесія документу

Кожен успішний OpenDocumentAsync створює одну сесію в IMemoryCache:

  • завантажений переглядач формату (екземпляр движка документу, що тримає розпарсений документ),
  • стан на кожній сторінці — обертання, відзеркалення та дані анотацій, які користувач застосовує у віджеті,
  • необов’язковий індекс пошуку, створюється ліниво під час першого пошуку (або завантажується з попередньо створеного .srh файлу, коли сторінки подаються зі спільного сховища),
  • сесійний водяний знак з DocOptions.Watermark.

Термін дії

Сесії закінчуються за ковзним вікном: 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 сесії 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. Два практичних наслідки:

  • Клієнт повинен надсилати cookie сесії ASP.NET разом із запитами сторінок. Налаштування крос‑доменної роботи, які видаляють cookie (або API‑клієнт без cookie‑скриньки), не пройдуть перевірку — це працююча функція, а не баг.
  • options.UnsafeMode = true повністю вимикає прив’язку. Вона існує для контрольованих сценаріїв; залишайте її false у продакшн‑середовищі на одному вузлі.

Зверніть увагу на написання. У попередній бібліотеці .NET Standard ця властивість називалась UnSafeMode і передавалась у посередницьке ПЗ; тут вона UnsafeMode і встановлюється один раз всередині AddDoconut().

Прив’язка токенів контролюється виключно цим глобальним перемикачем UnsafeMode — вона ввімкнена за замовчуванням (UnsafeMode = false) і застосовується до кожної сесії. Немає можливості відключити її для окремого документу; встановлення UnsafeMode = true вимикає прив’язку глобально.

Доступи та автентифіковані користувачі

Коли UnsafeMode дорівнює false, UseDoconut() автоматично вставляє посередницьке ПЗ доступу до документу перед посередницьким ПЗ сторінки. Не реєструйте його вдруге. Коли запит містить токен, система шукає надачу доступу, записану під час відкриття документу, і авторизує лише за умови, що виконуються усі наступні вимоги:

  1. надача існує для токену,
  2. вона не прострочена (термін дії надачі = TimeOut документу),
  3. ідентифікатор ASP.NET сесії, що запитує, збігається з тим, що відкрив документ,
  4. якщо відкривач був автентифікований, то вимога NameIdentifier користувача також збігається.

Невдачі повертають 403 — як PNG‑зображення помилки для запитів сторінок/мініатюр, як простий текст в інших випадках. Повідомлення та ключ запиту токену беруться з 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() пропускає посередницьке ПЗ доступу, і перевірка маркера також вимикається.

Безпека на кількох вузлах

Токени, прив’язані до сесії, передбачають, що вузол, який обслужує сторінку, також бачив запит, що відкрив документ. Це припущення не виконується, коли кілька вузлів обслужують ті ж документи зі спільного сховища: запит сторінки може потрапити на вузол, який ніколи не бачив відкриття, і перевірка за сесією його відхилить.

Відповідь — не залишати документи незахищеними. Використовуйте підписані квитки доступу через AddDoconutDistributedDocumentSecurity(...), що замінює перевірку сесії на облікові дані, які кожен вузол може перевіряти самостійно. Повна схема описана у Розподілені розгортання.

Відкликання

CloseDocument(token) не лише звільняє пам’ять — він також видаляє маркер secure-{token} і відкликає надачу доступу, тому закритий токен одразу стає недійсним на обох рівнях безпеки.

Контрольний список для продакшн

  • Тримайте UnsafeMode = false (за замовчуванням) на одному вузлі — цей глобальний перемикач саме прив’язує токени до сесій.
  • Зареєструйте AddDistributedMemoryCache() (у MVC та Razor Pages застосунках він вже є) і AddSession(), і викличте app.UseSession() перед гілкою посередницького ПЗ Doconut.
  • Переконайтеся, що політика вашого cookie сесії дозволяє запитам віджету передавати cookie (SameSite, HTTPS).
  • Використовуйте CloseDocument, коли користувач залишає документ — це одночасно економить пам’ять і підвищує безпеку.
  • Ніколи не журналюйте і не діліться токенами; розглядайте їх як короткоживучі облікові дані.
  • Обслуговуєте документи зі спільного сховища? Перейдіть на підписані квитки доступу, а не на прийняття незахищених документів.

Чи була ця сторінка корисною?