الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

الطريقة الاسهل لعمل Authentication

بدأه madani في 24 مارس 2008 · 4 رد · 1,360 مشاهدة · في ASP.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

شد انتباهي ان الكثير من الاخوة ما زالوا يعتمدون على ال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));

تم تعديل هذه المشاركة بواسطة madani في 25 مارس 2008 في 00:02

1
#2

أحسنت أخي الكريم .. ولكن ألا ترى أن Authentication عبر Session سيوفر كثير من الكود وكثير من الكتابة ولا سيما لو وضعناه ليس في كل صفحة ولكن في صفحة MasterPage فقط مثلاً وبذلك لن نكرر في كوده ؟!

على كل حال جزاك الله كل خير ولا حرمنا الله من علمك

أخيك محمد قناوي

ASP.NET Team Leader

moh_kin_mah@hotmail.com

--------------------------------

لو أعجبك أي من مشاركاتي ... برجاء قم بتقييم المشاركة عبر الأزرار الموجودة أسفل يسار كل مشاركة

#3

السلام عليكم ورحمة الله

مشكور اخي الكريم على هذه المقالة وعلى هذا التوضيح فكلامك صحيح فما زال بعض الاخوة يستخدمون طرق قديمة للتحقق من الصلاحيات مع ان الادوات الخاصة بهذا الامر login Tools والتي تعتمد على ASP.NET Memership Provider هي سهلة جدا حتى لاتحتاج كتابة كود وانما من خلال المعالج Asp.net Configuration يتم التحكم بالصلاحيات والادوار وما الى ذلك

#4
moh_kin كتب:
ألا ترى أن Authentication عبر Session سيوفر كثير من الكود وكثير من الكتابة

لم افهم هذه النقطة ,فالطريقة التي تقدم ذكرها لا تحتاج كثيرا من الكتابة فالكود الذي تكتبه عند نقر زر الدخول لا يختلف كثيرا عن 4 او 5 اسطر و بذلك تتم عملية نقل التحكم بامان الموقع من الكود الى ملفات الاعدادات ,اي Declarative Security

بالنسبة للMaster Page فعلى حد علمي ان كود الحدث Page_Load الخاص بالcontent page يتم تنفيذه قبل كود Page_Load الخاص بالMaster Page وهذا شيء سلبي لانك لو كان لديك كود ربط مع قاعدة البيانات و عمل binding لGridView او عمليات معقدة فسيتم ذلك قبل ان يتم التحقق من قيم الSession وقس على ذلك.

#5

نعم أخي الكريم كلامك صحيح .. وبالتحديد في الجزء الخاص Page_Load للمحتوى قبل MasterPage

ولكن في أحيان كثيرة يجب أن نعمل وفق الطريقة التقليدية .. ليس لأنها أفضل ولكنها تكون انسب لأسباب أخرى:

1- أن يكون الموقع شديد الديناميكية .. بمعنى الصلاحيات وأنواع المستخدمين يتم تشكيلهم بالكامل من داخل الموقع نفسه

2- أن يعتمد الموقع على Components جاهزة من النوع القديم لإدارة الصلاحيات

هذا والله أعلم وجزاك الله خير الجزاء أخي الحبيب

أخيك محمد قناوي

ASP.NET Team Leader

moh_kin_mah@hotmail.com

--------------------------------

لو أعجبك أي من مشاركاتي ... برجاء قم بتقييم المشاركة عبر الأزرار الموجودة أسفل يسار كل مشاركة

مواضيع مشابهة