المصادقة والتفويض

المصادقة (Authentication) والتفويض (Authorization) فحصان منفصلان يجريهما النظام قبل أن ينفّذ أي طلب. فالمصادقة تجيب عن سؤال «من أنت؟»: تتحقق من هوية يدّعيها صاحب الطلب، مثل كلمة مرور ورمز لمرة واحدة عند تسجيل الدخول. والتفويض يجيب عن سؤال «ماذا يُسمح لك أن تفعل؟»: يقرر هل يحق لهذه الهوية تنفيذ هذا الإجراء على هذا المورد. فعندما تسجّل سارة دخولها إلى تطبيق للمصروفات، تثبت المصادقة أنها سارة، ويسمح لها التفويض بفتح مطالباتها هي، لا مطالبات زميلها، ولا الاعتماد الذي يخص مديرتها.

تحدث المصادقة عادةً مرة واحدة عند تسجيل الدخول، وتترك إثباتاً يرافق كل طلب لاحق، مثل ملف تعريف ارتباط الجلسة (Session Cookie) من درس ملفات تعريف الارتباط والجلسات، أو رمزاً (Token)؛ ويتحقق الخادم مع كل طلب من أن هذا الإثبات ما زال صالحاً. أما التفويض فيُجرى من جديد مع كل طلب من هذه الطلبات.

لماذا يهم

عيوب التحكم في الوصول من أخطر ما يجده المختبِر. فقائمة ⁦OWASP Top 10:2025⁩ تضع التحكم في الوصول المعطّل (Broken Access Control) في المرتبة الأولى (A01)، وتبدأ قائمة ⁦OWASP API Security Top 10 (2023)⁩ بالتفويض المعطوب على مستوى الكائن (Broken Object Level Authorization) في البند API1: تغيّر معرّفاً في الطلب فتتلقى بيانات شخص آخر. ولا يكشف الاستخدام العادي هذه العيوب، لأن المستخدمين الحقيقيين يتبعون الشاشات المصممة لأدوارهم. ولا يجدها إلا اختبار يطلب عمداً ما لا يحق للمستخدم الحالي الحصول عليه.

والتمييز بين الفحصين يسرّع فرز العيوب أيضاً: فالرمزان 401 و403 يشيران إلى أجزاء مختلفة من الشيفرة وإلى إصلاحات مختلفة.

فحصان، وبهذا الترتيب دائماً

تأتي المصادقة أولاً: يقدّم المستخدم، أو برنامج مستدعٍ، بيانات الاعتماد (Credentials) ويتحقق منها الخادم. وعوامل المصادقة (Authentication Factors) ثلاثة أنواع: شيء تعرفه (كلمة مرور)، وشيء تملكه (هاتف يستقبل رمزاً لمرة واحدة، أو مفتاح أمان)، وشيء من سماتك أنت (بصمة الإصبع). والمصادقة متعددة العوامل (MFA) تجمع نوعين مختلفين على الأقل؛ أما كلمة المرور مع سؤال أمان فنوع واحد. والنتيجة هوية يثق بها الخادم، تُحفظ في جلسة أو رمز.

ويأتي التفويض ثانياً ويعمل على تلك الهوية. يقارن الخادم من يطلب، وأي إجراء، وعلى أي مورد، بسياسة (Policy): دور («المديرون يعتمدون المطالبات»)، أو ملكية («الموظف يقرأ مطالباته فقط»)، أو سمات مثل الفريق أو حالة الحساب. وحتى الصفحة العامة تمر بالتفويض، لكن سياستها تسمح للزوار المجهولين.

  • الرفض افتراضياً (Deny by Default): كل ما لا تسمح به السياسة صراحةً يُرفض.
  • أقل الصلاحيات (Least Privilege): يحصل كل دور على الصلاحيات التي يحتاجها عمله فقط.
  • افحص كل طلب على الخادم. فإخفاء زر ليس تحكماً في الوصول، إذ يستطيع أي أحد إرسال الطلب دون الشاشة.
تتحقق المصادقة ممن يطلب وترفض بالرمز 401؛ ثم يتحقق التفويض مع كل طلب من أن هذه الهوية يحق لها تنفيذ هذا الإجراء على هذا المورد، ويرفض بالرمز 403.

المصادقةالفحص الأول

من يرسل هذا الطلب؟

  1. 1تقديم بيانات الاعتمادكلمة مرور، رمز لمرة واحدة، مفتاح أمان
  2. 2الخادم يتحقق منها
  3. 3تثبيت الهويةتُحفظ في ملف تعريف ارتباط الجلسة أو في رمز
متى يُجرى:
عند تسجيل الدخول، ثم يرافق كلَّ طلب لاحق إثباتٌ يعيد الخادم فحصه
يعتمد على:
العوامل: شيء تعرفه أو تملكه أو من سماتك أنت؛ وMFA تجمع نوعين
عندما يرفض:
الرمز 401 Unauthorized مع تحدٍّ في WWW-Authenticate
العيب المعتاد:
الخادم يلبّي طلباً بلا بيانات اعتماد صالحة
كيف تختبره:
إرسال الطلب بلا بيانات اعتماد، وببيانات خاطئة ومنتهية وملغاة

التفويضالفحص الثاني

هل يحق لهذه الهوية تنفيذ هذا الإجراء على هذا المورد؟

  1. 1يصل الطلب ومعه الهوية
  2. 2فحص السياسةالدور، والملكية، وسمات أخرى
  3. 3سماح أو رفضالرفض افتراضياً
متى يُجرى:
مع كل طلب، وعلى الخادم
يعتمد على:
سياسة تمنح كل دور أقل الصلاحيات اللازمة
عندما يرفض:
الرمز 403 Forbidden، أو 404 إذا كان العقد يخفي المورد
العيب المعتاد:
مستخدم يقرأ بيانات مستخدم آخر أو يغيّرها بتغيير معرّف
كيف تختبره:
إرسال الطلب نفسه بهويات مستخدمين وأدوار مختلفة

إخفاء الزر ليس تفويضاً: يجب أن يرفض الخادم الطلب نفسه.

401 أم 403: أيّ الفحصين رفض الطلب

تخصص RFC 9110 لكل فحص رمز حالة خاصاً به. فالرمز 401 Unauthorized يعني أن الطلب يفتقر إلى بيانات اعتماد صالحة للمصادقة: لم تُرسل أصلاً، أو كانت خاطئة أو منتهية الصلاحية أو ملغاة. ويجب (MUST) أن يرسل الخادم ترويسة WWW-Authenticate فيها تحدٍّ (Challenge) واحد على الأقل يبيّن طريقة المصادقة. ورغم اسمه، فالرمز 401 يخص المصادقة، والترويسة التي تحمل بيانات الاعتماد في الطلب اسمها Authorization، وهذا مربك بالقدر نفسه.

أما 403 Forbidden فيعني أن الخادم فهم الطلب ويرفضه. وإذا أُرسلت بيانات اعتماد، فالخادم يعدّها غير كافية، لذا لن يفيد تكرار الطلب بالبيانات نفسها. وتسمح RFC 9110 للخادم أيضاً بأن يجيب بالرمز 404 Not Found بدلاً من ذلك كي لا يكشف وجود المورد. وهذا سليم إذا نص عليه العقد، لكن يجب عندها أن يتلقى المورد المخفي والمورد غير الموجود الإجابة نفسها، وإلا كشف الفرق بينهما المعرّفات الموجودة.

# 1. No credentials: authentication fails
GET /api/claims/5531 HTTP/1.1
Host: api.expenses.test

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="expenses"

# 2. Omar's valid token, but claim 5531 is Sara's: authorization fails
GET /api/claims/5531 HTTP/1.1
Host: api.expenses.test
Authorization: Bearer <valid token of Omar>

HTTP/1.1 403 Forbidden

جرّبها: مرجع رموز حالة HTTP جرّبها: محلّل ترويسات HTTP

المخططات الشائعة في لمحة

المخطط (Scheme) هو الطريقة التي تنتقل بها بيانات الاعتماد أو إثبات الهوية مع الطلب. وتتناول وحدة اختبار الواجهات البرمجية كلاً منها بالتفصيل؛ وأياً كان المخطط يبقى السؤالان نفساهما: هل الإثبات صالح (وإلا فالرمز 401)، وهل يحق لهذه الهوية فعل ذلك (وإلا فالرمز 403)؟

  • ملف تعريف ارتباط الجلسة: بعد نموذج تسجيل الدخول يحتفظ الخادم بالجلسة ويرسل معرّفها في ملف تعريف ارتباط يعيده المتصفح مع كل طلب.
  • مصادقة Basic (RFC 7617): معرّف المستخدم وكلمة المرور مفصولَين بنقطتين رأسيتين (:) ومرمّزَين بترميز Base64، في ترويسة Authorization مع كل طلب. وBase64 ليس تشفيراً، لذا لا تُقبل Basic إلا عبر HTTPS.
  • رمز Bearer (RFC 6750): رمز يُحصل عليه مرة واحدة، عند تسجيل الدخول مثلاً، ويُرسل بالصيغة Authorization: Bearer متبوعة بالرمز. ويستطيع كل من يحمله استخدامه حتى تنتهي صلاحيته أو يُلغى. وكثير منها رموز ويب JSON (JWT، RFC 7519) تحمل مطالبات (Claims) مقروءة تسمّي المستخدم وغالباً أدواره أو نطاقاته.
  • مفتاح API: سلسلة عشوائية طويلة تعرّف التطبيق المستدعي لا شخصاً بعينه، وتُرسل في ترويسة تحددها الواجهة. ولا يصفه معيار واحد.
  • إطار OAuth 2.0 (RFC 6749) وOpenID Connect: يُعد OAuth 2.0 إطار تفويض (Authorization Framework) يمنح التطبيق رمز وصول (Access Token) بصلاحيات محدودة تسمى النطاقات (Scopes)، دون أن يُطلعه على كلمة مرور المستخدم. ويضيف OpenID Connect فوقه طبقة هوية، وعليه تعتمد عادةً أزرار «تسجيل الدخول باستخدام…».

جرّبها: مفكّك ترميز JWT جرّبها: مفكّك ترميز Base64

مثال تطبيقي: من يحق له قراءة المطالبة واعتمادها

المتطلب: «يقدّم الموظفون مطالبات المصروفات ولا يعرضون إلا مطالباتهم. ويعرض المديرون مطالبات فريقهم ويعتمدونها، لكن ليس مطالباتهم هم أبداً. وتعيد الواجهة 401 دون رمز صالح، و403 عندما لا يحق للمستخدم تنفيذ الإجراء». مستخدمو الاختبار: سارة (Sara)، موظفة وصاحبة المطالبة 5531؛ وعمر (Omar)، موظف في فريق آخر؛ ولينا (Lina)، مديرة سارة وصاحبة المطالبة 5540.

الصفان 1 و2 يختبران المصادقة، والصفوف من 3 إلى 8 تختبر التفويض. والصف 4 هو الاختبار الكلاسيكي على مستوى الكائن: الصف 3 نفسه برمز مستخدم آخر، فالدور يحق له قراءة المطالبات لكن ليس هذه المطالبة. والصف 6 اختبار على مستوى الوظيفة: لا يحق للموظف اعتماد أي مطالبة أصلاً (البند ⁦API5:2023⁩ في OWASP: التفويض المعطوب على مستوى الوظيفة، Broken Function Level Authorization). وبعد كل عملية كتابة مرفوضة، تأكد أن شيئاً لم يتغير: تبقى المطالبة 5531 بحالة «submitted» بعد الصف 6، ولا تُعتمد المطالبة 5540 بعد الصف 7.

#  Caller               Request                        Expected  What it checks
1  no token             GET  /api/claims/5531          401       authentication
2  Sara, expired token  GET  /api/claims/5531          401       authentication
3  Sara                 GET  /api/claims/5531          200       owner may read
4  Omar                 GET  /api/claims/5531          403       not the owner
5  Lina                 GET  /api/claims/5531          200       manager of the team
6  Sara                 POST /api/claims/5531/approve  403       employees cannot approve
7  Lina                 POST /api/claims/5540/approve  403       never your own claim
8  Lina                 POST /api/claims/5531/approve  200       manager approves

جرّبها: مختبِر مصادقة API

أخطاء شائعة

  • اختبار كل دور عبر شاشاته فقط بدلاً من إرسال طلبات لا تعرضها الشاشات، مثل أن يطلب عمر مطالبة سارة.
  • قبول أي رمز 4xx: الطلب بلا رمز يحتاج إلى 401 مع WWW-Authenticate، والإجراء الممنوع إلى 403 (أو 404 إذا كان العقد يخفي الموارد)، والكتابة المرفوضة يجب أن تترك البيانات دون تغيير.
  • التحقق من أن الزر مخفي أو معطّل، دون إرسال الطلب الذي خلفه أبداً.
  • الاختبار بحساب مسؤول (Admin) واحد، ينجح في كل فحص تفويض ولذلك لا يختبر أياً منها.
  • نسيان أن الصلاحيات تتغير: المستخدم الذي أُزيل من فريق أو عُطّل حسابه قد تبقى جلسته مفتوحة.

من منظور ضمان الجودة

اطرح أسئلة التفويض أثناء التنقيح (Refinement): ما الأدوار الموجودة، ومن يملك كل نوع من السجلات، وماذا يحق لكل دور أن يفعل، وأي رمز حالة يعود عند الرفض. وكثير من الفرق تحفظ ذلك في مصفوفة صلاحيات (Permission Matrix): الأدوار في الصفوف، والإجراءات في الأعمدة، و«مسموح» أو «ممنوع» في كل خلية؛ وتصبح كل خلية حالة اختبار إيجابية أو سلبية. واتفق مبكراً على حسابات اختبار لكل دور، بما فيها مستخدم من فريق آخر، لأن اختبارات التفويض تحتاج دائماً إلى مستخدمَين اثنين على الأقل.

في تقرير الخطأ، سمِّ الفحص والهويتين كلتيهما: «عمر (موظف، الفريق B) يتلقى 200 ومطالبة سارة عند طلب GET /api/claims/5531؛ والمتوقع 403». أخفِ الرموز وكلمات المرور. وكثيراً ما تُعطى عيوب التحكم في الوصول درجة خطورة (Severity) حرجة (Critical) أو رئيسية (Major)، لأنها تكشف أو تغيّر بيانات لا يحق للمستخدم الوصول إليها. ولا تختبر إلا أنظمة تملكها أو لديك إذن مكتوب باختبارها، بحسابات اختبار لا ببيانات اعتماد مستخدمين حقيقيين.

تمرين عملي

صنّف وتوقّع: بوابة حجز في عيادة

المطلوب

لبوابة عيادة ثلاثة أدوار. المرضى لا يعرضون إلا مواعيدهم. وموظفو الاستقبال يعرضون جميع مواعيد عيادتهم ويعيدون جدولتها. والأطباء يعرضون المواعيد المحجوزة لديهم ويضيفون إليها ملاحظات. وتعيد الواجهة 401 دون جلسة صالحة، و403 عندما لا يحق للمستخدم تنفيذ الإجراء.

توقّع رمز الحالة لكل طلب أدناه، واذكر هل المصادقة أم التفويض هو ما يحدده. ثم أضف حالتي اختبار تنقصان القائمة.

المادة
Setup: appointment 812 = patient Huda, Dr. Faris, North clinic
       Noor = receptionist, North clinic; Rami = receptionist, South clinic
       Ali = another patient

#  Caller                  Request
1  no session              GET   /api/appointments/812
2  Huda                    GET   /api/appointments/812
3  Huda, session expired   GET   /api/appointments/812
4  Ali                     GET   /api/appointments/812
5  Noor                    PATCH /api/appointments/812        (new time)
6  Rami                    PATCH /api/appointments/812        (new time)
7  Dr. Faris               POST  /api/appointments/812/notes
8  Huda                    POST  /api/appointments/812/notes
الخطوات
  1. اقرأ أسطر الإعداد (Setup): من مريض الموعد 812، ولأي طبيب وأي عيادة يتبع؟
  2. لكل صف، اسأل أولاً هل المستدعي مُصادَق عليه، ثم هل تسمح السياسة بهذا الإجراء على هذا المورد.
  3. أضف حالتين لأدوار أو إجراءات أو حالات لا تغطيها القائمة.
إظهار الإجابة النموذجية
الإجابة النموذجية

الصفان 1 و3: الرمز 401، والمصادقة هي ما يحدده (لا بيانات اعتماد؛ جلسة منتهية). وتشترط RFC 9110 ترويسة WWW-Authenticate مع كل 401، فإن غابت فارفعها انحرافاً يقرر الفريق بشأنه.

الصف 2: الرمز 200، والتفويض يسمح به لأن هدى (Huda) هي المريضة. الصف 4: الرمز 403، تفويض على مستوى الكائن: علي (Ali) مُصادَق عليه لكنه ليس مريض الموعد 812.

الصف 5: رمز من فئة 2xx (عادةً 200، أو 204 إذا لم تحمل الاستجابة محتوى)، والتفويض يسمح به لأن نور (Noor) تعمل في العيادة نفسها. الصف 6: الرمز 403، تفويض على مستوى الكائن: يحق لموظفي الاستقبال إعادة الجدولة، لكن رامي (Rami) يعمل في عيادة أخرى؛ وبعدها تأكد أن وقت الموعد 812 لم يتغير.

الصف 7: رمز من فئة 2xx (الرمز 201 Created إذا أُنشئ مورد للملاحظة)، والتفويض يسمح به لأن الطبيب فارس (Dr. Faris) هو طبيب الموعد. الصف 8: الرمز 403، تفويض على مستوى الوظيفة: لا يحق للمرضى إضافة ملاحظات أصلاً.

حالات ناقصة، على سبيل المثال: طبيب آخر يضيف ملاحظة إلى الموعد 812 ← 403؛ وموظفة استقبال عُطّل حسابها وجلستها مفتوحة ترسل طلباً ← 401 أو 403 بحسب ما يحدده العقد؛ وهدى تطلب الموعد 99999 غير الموجود ← 404. ولاحظ أن الرد بالرمز 403 على موعد موجود و404 على موعد غير موجود يكشف للمستدعي المعرّفات الموجودة، فاسأل هل يقبل العقد ذلك.

أسئلة شائعة

هل OAuth 2.0 مصادقة أم تفويض؟

يُعد OAuth 2.0 إطار تفويض: يمنح التطبيق رمز وصول بصلاحيات محدودة، ولا يخبر التطبيق بمفرده من هو المستخدم. ويضيف OpenID Connect طبقة الهوية هذه فوق OAuth 2.0 عبر رمز الهوية (ID Token)، ولهذا تستخدم ميزات «تسجيل الدخول باستخدام…» بروتوكول OpenID Connect.

لماذا يسمى الرمز 401 «Unauthorized» وهو يخص المصادقة؟

الاسم موروث من الإصدارات الأولى لبروتوكول HTTP، وأبقت عليه RFC 9110. والمهم هو التعريف: 401 يعني أن الطلب يفتقر إلى بيانات اعتماد صالحة للمصادقة، ويجب أن يرسل الخادم معه WWW-Authenticate. أما 403 فيعني أن الخادم فهم الطلب ويرفضه. اعتمد على التعريف لا على الاسم.

هل يعيد المورد الممنوع الرمز 403 أم 404؟

كلاهما قد يكون صحيحاً. فالرمز 403 هو الإجابة المباشرة، وتسمح RFC 9110 للخادم بأن يجيب بالرمز 404 بدلاً منه إذا أراد إخفاء وجود المورد، مثل أرقام طلبات العملاء الآخرين. اختبر ما ينص عليه العقد، وتحقق من أن المورد المخفي والمورد غير الموجود يتلقيان الاستجابة نفسها تماماً.

لماذا يعرض تطبيق الويب صفحة تسجيل الدخول بدلاً من الرمز 401؟

يريد تطبيق الويب أن يعرض نموذج تسجيل الدخول الخاص به، لذلك يعيد عادةً توجيه الزائر المجهول إلى صفحة تسجيل الدخول بدلاً من إعادة 401، ويعرض على المستخدم الذي لا يملك الصلاحية صفحة ودّية تقول «لا تملك صلاحية الوصول». وهذا مقبول إذا نص عليه المتطلب. وتأكد في أدوات المطور في المتصفح أن الاستجابة التي خلف تلك الصفحة لا تحتوي البيانات المحمية.

المراجع

  • RFC 9110: HTTP SemanticsIETF · 2022معاني أساليب HTTP وحقول الترويسات ورموز الحالة والتفاوض على المحتوى، بغضّ النظر عن إصدار البروتوكول.
  • OWASP Top 10:2025OWASP Foundation · 2025أخطر عشرة مخاطر أمنية لتطبيقات الويب، مع كيفية اختبار كل منها والوقاية منه.
  • OWASP Cheat Sheet Series: AuthorizationOWASP Foundationضبط الوصول بالشكل الصحيح: أقل الصلاحيات، والرفض افتراضياً، والتحقق من الصلاحيات في كل طلب، وتفضيل النماذج المبنية على السمات أو العلاقات، واختبار منطق التفويض.
  • OWASP API Security Top 10 (2023)OWASP Foundation · 2023أكثر عشر نقاط ضعف شيوعاً في واجهات API: خلل التفويض على مستوى الكائن، وخلل التوثيق، والاستهلاك غير المقيد للموارد، وغيرها.

تدرّب بأدوات متقن

اختبر مصادقة Bearer وBasic ومفتاح API والترويسات المخصّصة على نقطة نهاية وقارن الاستجابات المصرّح بها بغير المصرّح بها.

اختبار واجهات API

ابحث عن أي رمز حالة HTTP لمعرفة معناه ومرجعه في RFC ومتى يُستخدم.

الويب

تحليل ترويسات طلبات واستجابات HTTP الخام إلى جدول منظّم مع الشروحات.

الويب

فكّ ترميز ترويسة JWT وحمولته، وفحص المطالبات (claims) والتحقق من انتهاء الصلاحية — بالكامل داخل متصفحك.

الأمان

فكّ ترميز سلاسل Base64 أو Base64url إلى نص، مع إصلاح الحشو تلقائياً.

الترميز

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة