اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
چهار دقیقه
فرمت کوکیهای ASP.NET Identity از پروژهی سورس باز Katana دریافت شدهاست و تولید آن پس از لاگین کاربر، شامل مراحل زیر میباشد:
1- با استفاده از کلاس ApplicationUser، شیء ClaimsPrincipal را تولید میکند.
2- به این ClaimsPrincipal اطلاعاتی مانند ApplicationUser.Id و SecurityStamp اضافه میشوند.
3- در ادامه، ClaimsPrincipal به OWIN و کلاس CookieAuthenticationHandler آن ارسال میشود.
4- کار کلاس CookieAuthenticationHandler، تولید و تنظیم اطلاعاتی مانند تاریخ صدور کوکی، تاریخ انقضای آن، نوع کوکی، مانند ماندگار بودن یا امن بودن (HTTPS) و امثال آن است. حاصل این مراحله، تولید یک AuthenticationTicket است.
5- در آخر، AuthenticationTicket و ClaimsPrincipal به کلاس SecureDataFormat، برای ابتدا، serialize شدن اشیاء، رمزنگاری و در نهایت تبدیل آنها به فرمت base64، ارسال میشوند.
جزئیات تکمیلی مرحلهی آخر آن نیز به این ترتیب است:
AuthenticationTicket با استفاده از کلاس TicketSerializer سریالایز میشود. پس از آن یک memory stream تشکیل شده و اطلاعات ClaimsIdentity و AuthenticationTicket سریالایز شده به آن ارسال میشوند. این memory stream با استفاده از الگوریتم GZip فشرده شده و برای پردازش بیشتر بازگشت داده میشود. مرحلهی بعد، رمزنگاری اطلاعات فشرده سازی شدهاست. برای این منظور از کلاس DpapiDataProtector دات نت استفاده میکنند. پس از رمزنگاری، استریم نهایی با فرمت base64 برای درج در HTTP Response آماده خواهد شد.
سؤال: چرا کوکیهای یک کاربر معین لاگین شدهی توسط ASP.NET Identity، در مرورگرهای مختلف متفاوت است؟
هرچند اطلاعاتی مانند ApplicationUser.Id و SecurityStamp برای یک کاربر، در مرورگرهای مختلف یکسان هستند، اما در مرحلهی چهارم، ذکر شد که AuthenticationTicket دارای اطلاعات بیشتری مانند زمان تولید کوکی نیز هست. بنابراین اطلاعات نهایی رمزنگاری شدهی در این حالت که در زمانهای مختلفی تولید شدهاند، یکسان نخواهند بود.
سؤال: در ساب دومینهای مختلف دومین مشخصی، چندین برنامهی مختلف نصب شدهاند. چگونه میتوان از یک سیستم لاگین ASP.NET Identity برای تمام آنها استفاده کرد؟
برای این منظور نیاز هست خاصیت CookieDomain را به صورت صریح مقدار دهی کرد. برای اینکار فایل Startup.Auth.cs را گشوده و CookieAuthenticationOptions را تنظیم کنید:
البته کار به همینجا ختم نمیشود. پس از آن نیاز است به ازای تمام دومینهای موجود، یک machine key مشخص تنظیم شود. از این جهت که در مرحلهی پنجم تولید کوکی، کلاس DpapiDataProtector دات نت، از machine key موجود، برای رمزنگاری اطلاعات استفاده میکند و اگر این machine key، به ازای برنامههای مختلف متفاوت باشد، کوکی تولید شده، قابل رمزگشایی و استفاده نخواهد بود.
برای اینکار به کنسول IIS مراجعه کرده و گزینهی machine key آنرا بیابید. در این قسمت بر روی generate keys کلیک کرده و اطلاعات تولیدی را باید به تمام web.configهای موجود کپی کنید:
سؤال: برنامههای مختلفی بر روی یک دومین نصب هستند، اما قصد نداریم از سیستم اعتبارسنجی یکپارچهای برای تمام آنها استفاده کنیم. اما اگر در یکی لاگین کنیم، بلافاصله لاگین در برنامهی دوم منقضی میشود، چرا؟
شبیه به همین مساله با Forms Authentication هم وجود دارد. برای رفع آن باید نام کوکیهای هر برنامه را منحصربفرد کنید و از نام پیش فرض کوکیها استفاده نکنید تا بر روی یکدیگر بازنویسی نشوند. برای اینکار خاصیت CookieName شیء CookieAuthenticationOptions را جداگانه مقدار دهی کنید:
سؤال: لاگین انجام شدهی در برنامهای که از ASP.NET Identity استفاده میکند، زود منقضی میشود؛ چرا؟
برای تنظیم صریح زمان انقضای کوکی ASP.NET Identity نیاز است خاصیت ExpireTimeSpan آنرا مقدار دهی کنید:
سؤال: کاربر سیستم ASP.NET Identity از سیستم خارج شدهاست (log off کرده) ولی هنوز میتوان از کوکی پیشین او برای اعتبارسنجی مجدد استفاده کرد. چطور میتوان این نقیصهی امنیتی را برطرف کرد؟
مشکل از اینجا است:
در مثال رسمی ASP.NET Identity یک چنین کدی برای خروج از سیستم ارائه شدهاست. نمونهی امنتر آن به صورت زیر است:
در اینجا علاوه بر عدم استفادهی از متد بدون پارامتر SignOut (با توجه به خاصیت AuthenticationType ذکر شدهی در CookieAuthenticationOptions)، کار به روز رسانی مجدد SecurityStamp کوکی نیز انجام شدهاست. با این تغییر، کوکی موجود بلا استفاده خواهد شد؛ چون دیگر قابل رمزگشایی نیست.
همچنین بهتر است مقدار validateInterval مربوط به SecurityStampValidator.OnValidateIdentity که به صورت پیش فرض 30 دقیقه است را به مقدار کمتری مانند 5 دقیقه تغییر دهید (تنظیمات OnValidateIdentity مربوط به CookieAuthenticationOptions فایل آغارین برنامه). کار این تنظیم، بررسی اعتبار کوکی، در بازههای زمانی مشخص شدهاست.
1- با استفاده از کلاس ApplicationUser، شیء ClaimsPrincipal را تولید میکند.
2- به این ClaimsPrincipal اطلاعاتی مانند ApplicationUser.Id و SecurityStamp اضافه میشوند.
3- در ادامه، ClaimsPrincipal به OWIN و کلاس CookieAuthenticationHandler آن ارسال میشود.
4- کار کلاس CookieAuthenticationHandler، تولید و تنظیم اطلاعاتی مانند تاریخ صدور کوکی، تاریخ انقضای آن، نوع کوکی، مانند ماندگار بودن یا امن بودن (HTTPS) و امثال آن است. حاصل این مراحله، تولید یک AuthenticationTicket است.
5- در آخر، AuthenticationTicket و ClaimsPrincipal به کلاس SecureDataFormat، برای ابتدا، serialize شدن اشیاء، رمزنگاری و در نهایت تبدیل آنها به فرمت base64، ارسال میشوند.
جزئیات تکمیلی مرحلهی آخر آن نیز به این ترتیب است:
AuthenticationTicket با استفاده از کلاس TicketSerializer سریالایز میشود. پس از آن یک memory stream تشکیل شده و اطلاعات ClaimsIdentity و AuthenticationTicket سریالایز شده به آن ارسال میشوند. این memory stream با استفاده از الگوریتم GZip فشرده شده و برای پردازش بیشتر بازگشت داده میشود. مرحلهی بعد، رمزنگاری اطلاعات فشرده سازی شدهاست. برای این منظور از کلاس DpapiDataProtector دات نت استفاده میکنند. پس از رمزنگاری، استریم نهایی با فرمت base64 برای درج در HTTP Response آماده خواهد شد.
سؤال: چرا کوکیهای یک کاربر معین لاگین شدهی توسط ASP.NET Identity، در مرورگرهای مختلف متفاوت است؟
هرچند اطلاعاتی مانند ApplicationUser.Id و SecurityStamp برای یک کاربر، در مرورگرهای مختلف یکسان هستند، اما در مرحلهی چهارم، ذکر شد که AuthenticationTicket دارای اطلاعات بیشتری مانند زمان تولید کوکی نیز هست. بنابراین اطلاعات نهایی رمزنگاری شدهی در این حالت که در زمانهای مختلفی تولید شدهاند، یکسان نخواهند بود.
سؤال: در ساب دومینهای مختلف دومین مشخصی، چندین برنامهی مختلف نصب شدهاند. چگونه میتوان از یک سیستم لاگین ASP.NET Identity برای تمام آنها استفاده کرد؟
برای این منظور نیاز هست خاصیت CookieDomain را به صورت صریح مقدار دهی کرد. برای اینکار فایل Startup.Auth.cs را گشوده و CookieAuthenticationOptions را تنظیم کنید:
var cookieAuthenticationOptions = new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), CookieDomain = ".mydomain.com" };
برای اینکار به کنسول IIS مراجعه کرده و گزینهی machine key آنرا بیابید. در این قسمت بر روی generate keys کلیک کرده و اطلاعات تولیدی را باید به تمام web.configهای موجود کپی کنید:
<machineKey validationKey="DAD9E2B0F9..." decryptionKey="ADD1C39C02..." validation="SHA1" decryption="AES" />
سؤال: برنامههای مختلفی بر روی یک دومین نصب هستند، اما قصد نداریم از سیستم اعتبارسنجی یکپارچهای برای تمام آنها استفاده کنیم. اما اگر در یکی لاگین کنیم، بلافاصله لاگین در برنامهی دوم منقضی میشود، چرا؟
شبیه به همین مساله با Forms Authentication هم وجود دارد. برای رفع آن باید نام کوکیهای هر برنامه را منحصربفرد کنید و از نام پیش فرض کوکیها استفاده نکنید تا بر روی یکدیگر بازنویسی نشوند. برای اینکار خاصیت CookieName شیء CookieAuthenticationOptions را جداگانه مقدار دهی کنید:
CookieName = "my-very-own-cookie-name"
سؤال: لاگین انجام شدهی در برنامهای که از ASP.NET Identity استفاده میکند، زود منقضی میشود؛ چرا؟
برای تنظیم صریح زمان انقضای کوکی ASP.NET Identity نیاز است خاصیت ExpireTimeSpan آنرا مقدار دهی کنید:
app.UseCookieAuthentication(new CookieAuthenticationOptions { ExpireTimeSpan = TimeSpan.FromHours(24.0), });
سؤال: کاربر سیستم ASP.NET Identity از سیستم خارج شدهاست (log off کرده) ولی هنوز میتوان از کوکی پیشین او برای اعتبارسنجی مجدد استفاده کرد. چطور میتوان این نقیصهی امنیتی را برطرف کرد؟
مشکل از اینجا است:
public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); }
[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> LogOff() { var user = await UserManager.FindByNameAsync(User.Identity.Name); AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); await UserManager.UpdateSecurityStampAsync(user.Id); return RedirectToAction("Login", "Account"); }
همچنین بهتر است مقدار validateInterval مربوط به SecurityStampValidator.OnValidateIdentity که به صورت پیش فرض 30 دقیقه است را به مقدار کمتری مانند 5 دقیقه تغییر دهید (تنظیمات OnValidateIdentity مربوط به CookieAuthenticationOptions فایل آغارین برنامه). کار این تنظیم، بررسی اعتبار کوکی، در بازههای زمانی مشخص شدهاست.