شد انتباهي ان الكثير من الاخوة ما زالوا يعتمدون على الSession لعمل authentication ويقومون بمقارنة القيم المحفوظة في الSession في اعلى كل صفحة للتحقق من ان المستخدم قد دخل فعلا الى الموقع باستخدام اسم المستخدم و كلمة المرور.
اريد ان اشير الى امور معينة:
-نحن نتحدث عن الFormAuthentication اي الدخول الى الموقع عن طريق فورم (لن يتم التطرق الى الطريقة الاحدث في هذا المجال الا وهي الASP.NET Memership Provider)
-الSession قد انتهى دورها كطريقة لعمل الAuthentication منذ مجيء الASP.NET,يمكنك الان حفظ اسم المستخدم و الادوار Roles في الكائن FormsAuthenticationTicket
-يتم التحكم في امان الصفحات عن طريق الweb.config
المثال:
لو كان لدينا الصفحة الرئيسية Default.aspx متاحة لكل المستخدمين و الصفحة Author.aspx متاحة فقط للمستخدمين الذين ينتمون الى الدور او المجموعة author ,نقوم بانشاء صفحة الدخول login بها حقلي نص لادخال اسم المستخدم و كلمة السر و زر للدخول.
الان عند النقر على الزر نقوم بالتحقق من المستخدم بالربط مع قاعدة البيانات ولو افترضنا اننا تحققنا من المستخدم و كان اسمه madani و كان ضمن المجموعتين user و author,نقوم بانشاء الكائن FormsAuthenticationTicket :
protected void Button1_Click(object sender, EventArgs e)
{
string username = "madani";
string roles = "user,author";
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1,username, DateTime.Now, DateTime.Now.AddMinutes(30), true, roles);
HttpCookie ht = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat));
Response.Cookies.Add(ht);
Response.Redirect(FormsAuthentication.GetRedirectUrl(username,true));
}الكود اعلاه ينشأ الكائن FormsAuthenticationTicket باستخدام المدخلات:
1 هو رقم الticket ويمكنك دائما جعله بنفس القيمة
username هو اسم المستخدم الذي سيحفظ في الكوكيز.
DateTime.Now هو تاريخ انشاء الكوكيز
DateTime.Now.AddMinutes(30) معناه ان الكويز سينتهي بعد 30 دقيقة
true معناه اننا نريد حفظ الكوكيز في جهاز المستخدم
roles هي قائمة المجموعات التي ينتمي اليها المستخدم ,سيتم الاعتماد على هذة القيمة عند التحقق من الصلاحيان عن طريق web.config
في السطر الخامس يتم انشاء الكوكيز و عمل Encrypt لقيمها,ثم تتم اضافتها الى الResponse .
الان ننشأ الملف Global.asax من Add New Item->Global Application Class ,ثم نضيف الحدث Application_AuthenticateRequest.هذا الحدث يتم تشغيله كلما تم تشغيل صفحة من صفحات الموقع ,لذلك بدل ان نتعب حالنا بمقارنة قيم الsession في اعلى كل صفحة ,نقوم باسناد قيم المجموعات roles و الticket الى المستخدم:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
FormsIdentity fi = (FormsIdentity)User.Identity;
FormsAuthenticationTicket fat = fi.Ticket;
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(fi, fat.UserData.Split(','));
}
}كلما قمنا به هو استخراج الكائن FormsAuthenticationTicket الذي تم حفظه في الكوكيز وحصلنا على قيم المجموعات roles ثم اسندناها الى الخاصية roles
ماهي النتيجة:
الان كيف نتحكم في الصلاحيات ؟.الباقي يجب عمله من خلال الweb.config :
<authentication mode="Forms"> <forms loginUrl="login.aspx" protection="All" timeout="30" name="MyApplicationTicketName"/> </authentication>
ثم نعلن اننا نسمح بدخول كل الزوار الى كل صفحات الموقع:
<authorization> <allow users="*"/> </authorization>
ماعدا صفحة Author.aspx فانها متاحة للمستخدمين المنتمين للمجموعة author:
<location path="Author.aspx"> <system.web> <authorization> <allow roles="author"/> <deny users="*"/> </authorization> </system.web> </location>
الان جرب ان تدخل الى اي صفحة فانك ستدخل بدون اي مشكلة ,لكن لو اردت الدخول الى الصفحة Author.aspx فانه سيحولك الى صفحة الدخول ولو قمت باسناد قيم المجموعات بشكل صحيح فستتمكن من الانتقال و عرض الصفحة بدون مشاكل.
هذا كل ماهو مطلوب لنظام صلاحيان مرن و سهل التعديل.كذلك يمكنك حفظ باقي القيم في الSession كالعادة.
لو اردت عرض اسم المستخدم ,كما تم حفظه في الكوكيز:
User.Identity.Name
انا انصح بحفظ اسم المستخدم ,مثلا madani ,في الSession بينما يتم حفظ الid في الكوكيز لاننا نستعمله كثيرا في عمليات قواعد البيانات للاضافة و الحذف و الاستعلام و يمكنك دائما تمريره الى استعلامات الSqlDataSource
اذا كان لديك صفحة متاحة لكل الزوار و اردت معرفة ان كان المستخدم قد دخل فعلا الى الموقع :
if(User.Identity.IsAuthenticated) //do something
قضايا متقدمة:
لو افترضنا ان لديك زر معين في صفحة ما و اردت ابرازه فقط للمستخدمين الذين ينتمون لمجموعة auothr :
Button1.Visible = User.IsInRole("author");لو احببت ان يتذكرك المتصفح IE,FireFox الخ عند اغلاقك للصفحة بحيث لا تحتاج الى الدخول مرة اخرى,فقط اضف السطر ht.Expires = fat.Expiration :
بالمناسبة يمكن عمل ذلك ك CheckBox مع النص Remeber Me:
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1,username, DateTime.Now, DateTime.Now.AddMinutes(30), true, roles); HttpCookie ht = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat)); if(CheckBox1.Checked) ht.Expires = fat.Expiration; Response.Cookies.Add(ht); Response.Redirect(FormsAuthentication.GetRedirectUrl(username,true));
