تسجيل الدخول عبر النموذج وHTTP Basic
تسجيل الدخول عبر النموذج وHTTP Basic
يأتي Spring Security مزوَّدًا بآليتين جاهزتين للمصادقة تغطيان أكثر أنماط تطبيقات الويب شيوعًا: تسجيل الدخول عبر النموذج (Form Login) للجلسات التي يقودها المتصفح، وHTTP Basic للعملاء من الأجهزة الآلية أو واجهات برمجة التطبيقات. في الدروس السابقة هيّأت SecurityFilterChain وأعددت UserDetailsService. الآن ستربط هذه القطع بسير عمل تسجيل الدخول الفعلية.
كيف تنتظم آليات المصادقة داخل سلسلة الفلاتر
كل آلية في Spring Security مُنفَّذة على شكل فلتر servlet يجلس داخل SecurityFilterChain. عندما يصل طلب، تمشي السلسلة عبر فلاترها بالترتيب. فلتران مرتبطان بهذا الدرس:
UsernamePasswordAuthenticationFilter— يعترضPOST /login، ويستخرج بيانات الاعتماد من جسم الطلب، ويفوّض الأمر إلىAuthenticationManager.BasicAuthenticationFilter— يقرأ الترويسةAuthorization: Basic <base64>في كل طلب ويحاول المصادقة قبل أن يصل الطلب إلى وحدات التحكم الخاصة بك.
لا تُنشئ هذه الفلاتر مباشرةً، بل يبنيها Spring Security عندما تستدعي .formLogin() أو .httpBasic() على DSL الخاص بـ HttpSecurity.
ضبط Form Login
أدنى إعداد ممكن يُفعِّل صفحة تسجيل الدخول المدمجة ويربط كل الإعدادات الافتراضية:
بهذا الإعداد وحده، يُعاد توجيه أي طلب غير مصادَق عليه لعنوان URL محمي إلى /login، يُصيّر Spring نموذج تسجيل الدخول المدمج، وعند نجاح POST إلى /login يُعاد توجيه المستخدم إلى العنوان الأصلي (أو /). عند الفشل يعود إلى /login?error.
تخصيص سير عمل Form Login
في المشاريع الحقيقية تريد دائمًا صفحة تسجيل دخول خاصة بك وعنوان نجاح مخصص ومعالج فشل محدد:
الفارق الجوهري: loginPage() هو نقطة نهاية GET تخدمها وحدة تحكم MVC الخاصة بك؛ أما loginProcessingUrl() فهو نقطة نهاية POST يعترضها فلتر Spring Security — لا تكتب أي دالة تحكم لها.
@Controller الخاص بك.
ضبط تسجيل الخروج
يتزاوج Form Login بشكل طبيعي مع معالج تسجيل خروج. يُسجّل Spring Security المسار POST /logout افتراضيًا، مما يُبطل الجلسة ويمسح SecurityContext. خصّصه هكذا:
<img src="/logout"> غير مرئي في أي صفحة لإجبار الضحية على تسجيل الخروج. يفرض Spring Security استخدام POST افتراضيًا — لا تغيّره إلى GET إلا إذا عطّلت حماية CSRF لذلك العنوان أيضًا.
ضبط HTTP Basic
يُفعَّل HTTP Basic باستدعاء واحد:
يُشفّر العميل بيانات الاعتماد كـ Base64(username:password) ويُرسلها في كل طلب داخل ترويسة Authorization. يُفكّك Spring Security ترميزها ويتحقق منها مقابل UserDetailsService في كل استدعاء.
HTTP Basic في الأنظمة الموزعة
في معماريات الخدمات المصغرة، يُستخدم HTTP Basic أحيانًا للمصادقة بين الخدمات عندما تكون الخدمات بالفعل داخل شبكة خاصة مع TLS متبادل، أو عندما يدور مدير أسرار مخصص بيانات الاعتماد تلقائيًا. ميزته البساطة — لا تبادل رمز، لا انتهاء صلاحية، لا تحديث. عيبه هو بالضبط ذلك: بيانات الاعتماد طويلة الأجل ولا يمكن إبطالها دون إعادة نشر جميع المستهلكين. لأي شيء يواجه المستخدمين أو عبر حدود الشبكة، يُفضَّل استخدام رموز JWT Bearer (مغطاة في البرنامج التعليمي التالي).
دمج كلتا الآليتين
نمط شائع هو تقديم واجهة مستخدم للمتصفح عبر Form Login وواجهة REST API عبر HTTP Basic (أو JWT) من نفس التطبيق، باستخدام حبتَي SecurityFilterChain منفصلتين مع أنماط securityMatcher مختلفة:
التعليق التوضيحي @Order بالغ الأهمية: يُقيّم Spring السلاسل بترتيب تصاعدي، لذا يجب أن يأتي المُطابق الأكثر تحديدًا (/api/**) أولًا. بدون @Order، يستخدم Spring Boot ترتيبًا افتراضيًا وقد يُطبّق السلسلة الخاطئة.
تذكّرني (Remember Me)
يدعم Form Login ملف تعريف ارتباط "تذكّرني" يُعيد مصادقة المستخدمين عبر الجلسات دون إعادة إدخال بيانات الاعتماد:
الرمز عبارة عن تجزئة لـ username + expiry + password-hash + key. يؤدي تغيير كلمة مرور المستخدم أو key تلقائيًا إلى إبطال جميع رموز "تذكّرني" القائمة — خاصية مفيدة لإجبار تسجيل الخروج عبر الأجهزة.
الخلاصة
Form Login وHTTP Basic هما آليتا المصادقة الأساسيتان في Spring Security. Form Login مبني لمستخدمي المتصفح: يدير صفحة تسجيل الدخول، ومعالجة POST، وإعادة التوجيه عند النجاح، وإنشاء الجلسة. HTTP Basic مبني للعملاء البرمجيين: يقرأ بيانات الاعتماد من ترويسة في كل طلب ويعمل بشكل أفضل كحالة عديمة الحالة. تضبط كليهما عبر DSL الخاص بـ HttpSecurity. في الإنتاج، اقرنهما دائمًا بـ HTTPS، واستخدم حبوب SecurityFilterChain منفصلة عندما يخدم تطبيق واحد كلًّا من المتصفحات ومستهلكي API.