セッションとセキュリティ

ドキュメントセッションとアクセス制御

Doconut トークンは強力です。これを提示した者は、オープンセッションにバインドされていなければ、ドキュメントのすべてのページを要求できてしまいます。このページでは、セッションが保持するもの、存続期間、そして UseDoconut() がデフォルトで有効にするチェックについて説明します。

ドキュメントセッションが保持するもの

各成功した OpenDocumentAsync は IMemoryCache に 1 つのセッションを作成します。

  • ロードされたフォーマットビューア(解析されたドキュメントを保持するドキュメントエンジンのインスタンス),
  • ページごとの状態 — 回転、フリップ、ウィジェットでユーザーが適用する注釈データ,
  • オプションの 検索インデックス、最初の検索時に遅延構築され(またはウェブファームシナリオで事前に作成された .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 は新しいトークンをそれを開いた HTTP リクエストの ASP.NET セッション にバインドし、secure-{token} マーカーをそのセッションに書き込みます。Doconut ミドルウェアは、他のブラウザセッションへのページ提供を拒否します。

  • 盗まれたトークンを提示した別のブラウザ/セッション → エラー画像 You Are Not Authorized To View This Page.
  • セッションミドルウェアが登録されていない → HTTP 500 Session middleware not configured. Call UseSession() before UseDoconut().

これが Quick Start が Doconut ブランチの前に AddSession() と app.UseSession() を必須としている理由です。実務上の影響は二つあります:

  • クライアントはページリクエストに ASP.NET セッションクッキー を送信する必要があります。クッキーを除去するクロスオリジン設定やクッキージャーを持たない API クライアントではチェックが失敗します — これはバグではなく機能が正しく動作していることを示します。
  • options.UnsafeMode = true はバインディングを完全に無効化します。これは制御されたシナリオ(例:サーバー間レンダリング)向けに存在します。運用環境では false のままにしてください。

トークンバインディングはこのグローバルな UnsafeMode スイッチだけで制御されます — デフォルトで有効(UnsafeMode = false)であり、すべてのセッションに適用されます。ドキュメント単位でのオプトアウトはなく、UnsafeMode = true に設定するとバインディングは全体で無効化されます。

アクセス権限と認証ユーザー

UnsafeMode が false の場合、UseDoconut() はページミドルウェアの前に DocumentAccessMiddleware を自動的に挿入します。二度登録しないでください。リクエストがトークンを持つと、ドキュメントが開かれた際に記録された アクセス権限 を検索し、以下すべてが満たされた場合にのみ認可します:

  1. トークンに対する権限が存在すること、
  2. 権限が期限切れでないこと(権限の有効期間はドキュメントの TimeOut と同じ)、
  3. リクエスト元の ASP.NET セッション ID がドキュメントを開いたときのものと一致すること、
  4. 開いたユーザーが認証済みの場合、リクエスト元ユーザーの NameIdentifier クレームも一致すること。

失敗した場合は 403 を返します — ページやサムネイルのリクエストでは PNG エラー画像として、その他ではプレーンテキストとして返されます。メッセージとトークンのクエリキーは DocumentSecurityOptions から取得されます(TokenQueryKey デフォルトは "token"、UnauthorizedMessage デフォルトは "You Are Not Authorized To View This Page.")。これらのオプションはアプリ構築前に ASP.NET Core の DI で設定してください。セッション状態が利用できない場合、ミドルウェアは 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} マーカーを削除し、アクセス権限も取り消すため、閉じられたトークンは即座に両方のセキュリティ層で無効になります。

本番環境向けチェックリスト

  • UnsafeMode = false(デフォルト)を維持してください — このグローバルスイッチがトークンをセッションにバインドします。
  • AddDistributedMemoryCache()(MVC と Razor Pages アプリは既に持っています)と AddSession() を登録し、Doconut ミドルウェアブランチの前に app.UseSession() を呼び出してください。
  • セッションクッキーのポリシーがウィジェットのリクエストでクッキーを送信できるように設定してください(SameSite、HTTPS)。
  • ユーザーがドキュメントを離れたときは CloseDocument を使用してください — メモリとセキュリティの両方が向上します。
  • トークンをログに記録したり共有したりしないでください;短命な認証情報として扱ってください。

このページは役に立ちましたか?