جلسات و امنیت

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

یک توکن Doconut یک سند باز را شناسایی می‌کند. اگر هر درخواستی که آن را حمل می‌کند سرو شود، هرکسی که آن را به دست آورد می‌تواند تمام صفحات را بخواند. این صفحه توضیح می‌دهد یک جلسه سند چه چیزی را در بر می‌گیرد، چه مدت طول می‌کشد، و چگونه DocImage.axd تصمیم می‌گیرد چه کسی می‌تواند صفحات آن را ببیند — روی یک سرور و در یک مزرعه وب.

آنچه یک جلسه سند در بر دارد

هر OpenDocumentAsync موفق یک جلسه ایجاد می‌کند که در حافظه نگه‌داری می‌شود:

  • نمایشگر فرمت بارگذاری‌شده — نمونهٔ موتور که سند تجزیه‌شده را نگه می‌دارد،
  • وضعیت صفحه به‌ازای هر صفحه — چرخش، وارونه‌سازی، و داده‌های حاشیه‌نویسی که کاربر در ویجت اعمال می‌کند،
  • فهرست جستجوی اختیاری، که در اولین جستجو ساخته می‌شود (یا از یک فایل پیش‌ساختهٔ .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 — پیش‌فرض — باز کردن یک سند دسترسی به نشست ASP.NET درخواست‌کننده‌ای که آن را باز کرده را اعطا می‌کند، با نوشتن یک ورودی secure-{token} در آن نشست. DocImage.axd به خود حالت نشست نیاز دارد و صفحه را فقط زمانی سرو می‌کند که نشست درخواست‌کننده آن ورودی را داشته باشد. هر مرورگر دیگری که همان توکن را ارائه دهد، تصویر خطایی با متن You Are Not Authorized To View This Page. دریافت می‌کند.

csharp
Doconut.DoconutHost.Initialize(options =>
{
    // false (پیش‌فرض): DocImage.axd فقط صفحه‌ای را به نشست ASP.NET که آن را باز کرده سرو می‌کند
    // سند. هندلر خودش وضعیت نشست را درخواست می‌کند؛ فقط نیاز دارد که سایت
    // وضعیت نشست را در Web.config خاموش کنید.
    options.UnsafeMode = false;
});

سه پیامد عملی:

  • نقطهٔ انتهایی باز کردن به حالت نشست نیاز دارد. کنترل‌کننده‌های MVC و صفحات Web Forms به‌طور پیش‌فرض آن را دارند. یک IHttpHandler سفارشی این را ندارد مگر اینکه System.Web.SessionState.IRequiresSessionState را پیاده‌سازی کند. باز کردن که بدون نشست اجرا شود، چیزی برای اعطا ندارد، بنابراین نمایشگر پیام «شما مجاز به مشاهده این صفحه نیستید.» را در هر صفحه نشان می‌دهد.
  • حالت نشست باید فعال بماند. <sessionState mode="Off" /> در Web.config هر دو اعطا و بررسی را غیرفعال می‌کند و هر صفحه‌ای رد می‌شود.
  • مرورگر باید کوکی نشست را ارسال کند. درخواست‌های ویجت هم‌منبع هستند، بنابراین به‌صورت خودکار ASP.NET_SessionId را حمل می‌کنند. کلاینتی بدون جعبهٔ کوکی — اسکریپت، تماس سرور‑به‑سرور، تنظیمات کراس‑اورجین که کوکی‌ها را حذف می‌کند — رد می‌شود. این همان ویژگی فعال است.

UnsafeMode = true بررسی را غیرفعال می‌کند: هر درخواستی که توکن را حمل کند سرو می‌شود. این یک سوئیچ سراسری برای هر سند است، بدون امکان بازنویسی برای هر سند. آن را false بگذارید.

لغو دسترسی

CloseDocument(token) بیش از آزادسازی حافظه عمل می‌کند: ورودی secure-{token} را از نشست درخواست فعلی حذف می‌کند و توکن را لغو می‌نماید، بنابراین توکن بسته‌شده بلافاصله رد می‌شود.

مزرعه‌های وب: بلیت‌های امضا شده

در یک مزرعه، درخواست بعدی می‌تواند به سروری برسد که هرگز سند را ندیده است، در یک فرایند کاری متفاوت، با نشست ASP.NET خود. اعطای نشست نمی‌تواند آن را دنبال کند. حالت توزیعی آن را با بلیت امضا شده که به مرورگر متصل است جایگزین می‌کند: هر گره یک مخزن برای جلسات سند و یک کلید امضا مشترک دارد، و DocImage.axd درخواست را زمانی می‌پذیرد که بلیت آن برای آن توکن، آن مرورگر، و — وقتی کاربر وارد شده باشد — آن کاربر معتبر باشد.

پیکربندی، یکسان در هر گره:

csharp
// Global.asax.cs - Application_Start
Doconut.DoconutHost.Initialize(
    options => options.UnsafeMode = false,     // بررسی بلیت فقط زمانی اجرا می‌شود که این مقدار false باشد
    services => services.AddDoconutDistributed(d =>
    {
        d.Store             = CloudLocation.FileShare;
        d.FileShareRootPath = @"\\fileserver\doconut-shared";  // یک پوشه که هر گره می‌تواند به آن دسترسی داشته باشد
        d.SigningKey        = farmKey;                          // حداقل ۳۲ بایت، یکسان بر روی هر گره
    }));

نقطهٔ انتهایی باز کردن سپس بلیت را به مرورگر قبل از باز کردن متصل می‌کند و بلیت را همراه با توکن برمی‌گرداند:

  • تنظیم DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(System.Web.HttpContext.Current, securityOptions) — که کوکی doconut-client را که بلیت به آن متصل است صادر می‌کند — و DocOptions.UserId = DoconutFarmBinding.ResolveUserId(System.Web.HttpContext.Current)؛
  • پس از OpenDocumentAsync، بازگرداندن viewer.AccessToken همراه با توکن؛
  • در صفحه، هر دو را به ویجت پاس می‌دهید: objViewer.View(token, access).

Doconut.MvcSample.WebFarm در بستهٔ نمونه‌ها یک گرهٔ مزرعهٔ کامل و قابل اجرا است، و راهنمای مهاجرت کنار آن هر گام را توضیح می‌دهد.

کلید امضا را خارج از کنترل نسخه نگه دارید: هم بلیت‌ها را امضا می‌کند و هم اسناد را در مخزن مشترک رمزنگاری می‌کند. گره‌ای با کلید متفاوت تمام بلیت‌های صادر شده توسط دیگران را رد می‌کند.

یک مزرعه را با مرورگر واقعی یا اسکریپتی که کوکی‌ها را نگه می‌دارد تست کنید. کلاینتی بدون کوکی doconut-client با 401 پاسخ داده نمی‌شود: تصویر خطای «not authorized» با وضعیت 200 دریافت می‌کند، حدود ۲ کیلوبایت، در حالی که یک صفحهٔ واقعی ده‌ها تا صدها کیلوبایت است.

فهرست بررسی تولید

  • نگه داشتن UnsafeMode = false (پیش‌فرض).
  • اسناد را از درخواست‌هایی که حالت نشست دارند باز کنید و هرگز حالت نشست را خاموش نکنید.
  • اطمینان حاصل کنید کوکی نشست به DocImage.axd می‌رسد (هم‌منبع، HTTPS، یک سیاست SameSite که اجازه می‌دهد).
  • در یک مزرعه، از حالت توزیعی با یک کلید امضا که توسط هر گره به اشتراک گذاشته می‌شود استفاده کنید.
  • هنگام خروج کاربر از سند، CloseDocument را فراخوانی کنید — هم حافظه و هم امنیت سود می‌برند.
  • هرگز توکن‌ها را لاگ یا به اشتراک نگذارید؛ آنها را به‌عنوان اعتبارهای کوتاه‌مدت در نظر بگیرید.

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