Сессии и безопасность
Сессии документов и контроль доступа
Токен Doconut обладает большой силой: любой, кто его предъявит, может запросить любую страницу документа, если он не привязан к открывающей сессии. Эта страница объясняет, что хранится в сессии, как долго она живёт и какие проверки включаются по умолчанию функцией UseDoconut().
Что хранит сессия документа
Каждый успешный OpenDocumentAsync создаёт одну сессию в IMemoryCache:
- загруженный просмотрщик формата (экземпляр движка документа, содержащий разобранный документ),
- состояние каждой страницы — вращение, отражения и данные аннотаций, которые пользователь применяет в виджете,
- необязательный поисковый индекс, создаваемый лениво при первом поиске (или загружаемый из заранее построенного файла
.srhв сценариях веб‑фермы), - водяной знак сессии, полученный из
DocOptions.Watermark.
Время жизни
Сессии истекают по скользящему окну: DocOptions.TimeOut минут (по умолчанию 60), сбрасываемому каждым запросом, предъявляющим токен. Когда сессия удаляется — из‑за истечения срока или вызова CloseDocument(token) — её callback освобождает движок документа и сразу освобождает связанную память.
// Краткоживущая сессия для однократного предварительного просмотра
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в продакшене.
Привязка токенов контролируется исключительно этим глобальным переключателем UnsafeMode — он включён по умолчанию (UnsafeMode = false) и применяется ко всем сессиям. Нет возможности отключить её для отдельного документа; установка UnsafeMode = true отключает привязку глобально.
Права доступа и аутентифицированные пользователи
Когда UnsafeMode установлен в false, UseDoconut() автоматически вставляет DocumentAccessMiddleware перед промежуточным ПО страниц. Не регистрируйте его повторно. Когда запрос содержит токен, он ищет право доступа, записанное при открытии документа, и авторизует только при выполнении всех условий:
- существует право доступа для токена,
- оно не истекло (срок действия права =
TimeOutдокумента), - ID запрашиваемой сессии ASP.NET совпадает с тем, который открыл документ,
- если открывший был аутентифицирован, то утверждение
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.
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} и отзывает право доступа, так что закрытый токен сразу становится недействительным на обоих уровнях безопасности.
Список проверок для продакшена
- Оставляйте
UnsafeMode = false(по умолчанию) — этот глобальный переключатель привязывает токены к сессиям. - Регистрируйте
AddSession()и вызывайтеapp.UseSession()перед веткой промежуточного ПО Doconut. - Убедитесь, что политика cookie сессии позволяет запросам виджета передавать cookie (
SameSite, HTTPS). - Используйте
CloseDocument, когда пользователь покидает документ — это выгодно и для памяти, и для безопасности. - Никогда не записывайте в логи и не делитесь токенами; рассматривайте их как краткосрочные учётные данные.
Была ли эта страница полезной?