جلسات و امنیت

جلسات سند و کنترل دسترسی

یک توکن 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 اصرار دارد. دو پیامد عملی:

  • مشتری باید کوکی جلسهٔ ASP.NET را همراه با درخواست‌های صفحه ارسال کند. تنظیمات Cross-origin که کوکی‌ها را حذف می‌کنند (یا یک کلاینت API بدون جعبهٔ کوکی) بررسی را شکست می‌دهند — این به‌معنی عملکرد صحیح است، نه یک باگ.
  • 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()، و قبل از شاخهٔ میدلور Doconut، app.UseSession() را فراخوانی کنید.
  • اطمینان حاصل کنید سیاست کوکی جلسهٔ شما اجازه می‌دهد درخواست‌های ویجت کوکی را حمل کنند (SameSite، HTTPS).
  • هنگام خروج کاربر از سند از CloseDocument استفاده کنید — هم حافظه و هم امنیت سود می‌برند.
  • هرگز توکن‌ها را لاگ یا به اشتراک نگذارید؛ آنها را به‌عنوان اعتبارنامه‌های کوتاه‌مدت در نظر بگیرید.
  • سرو کردن از ذخیره‌سازی مشترک؟ به بلیت‌های دسترسی امضا‌شده منتقل شوید به‌جای پذیرش اسناد بدون محافظت.

آیا این صفحه مفید بود؟