SSO والتضمين

لدينا مثيل Discourse مُعد مع SSO (باستخدام SAML/Shibboleth)، وقمت بإعداده للسماح بتضمين المحتوى على نطاق فرعي آخر يستخدم نفس نظام SSO.

إليك المشكلة التي أواجهها:

  1. يزور المستخدم صفحة على النطاق الفرعي X، والتي تضم موضوعًا من Discourse المضيف على النطاق الفرعي Y.
  2. يتم إعادة توجيه المستخدم إلى النطاق الفرعي Z لتسجيل الدخول عبر SSO. ثم يتم إعادة توجيهه مرة أخرى إلى النطاق الفرعي X.
  3. تقوم الصفحة على النطاق الفرعي X بجلب ملف JavaScript المضمن، الذي ينشئ إطارًا (iframe) يحاول جلب موضوع المنتدى. ومع ذلك، يعيد Discourse (النطاق الفرعي Y) توجيه الإطار إلى النطاق الفرعي Z لتسجيل الدخول عبر SSO، وبما أن المستخدم مسجل الدخول بالفعل، يتم إعادة توجيهه مرة أخرى إلى عنوان URL المضمن لـ Discourse. لكن هذا يؤدي إلى ظهور خطأ 400 “خطأ في التضمين”، لأن عنوان URL المرجعي (referer) يأتي الآن من النطاق الفرعي Z (نطاق SSO) بدلاً من النطاق الفرعي X (النطاق المعتمد/المُدرج في القائمة البيضاء للتضمين). ويعيد Discourse الرسالة “لم يتم إرسال عنوان URL المرجعي، أو أنه لا يطابق أيًا من المضيفين التاليين”.
  4. عند تحديث الصفحة، يعمل كل شيء بشكل مثالي (أي يتم جلب موضوع المنتدى بنجاح)، وعلى الأرجح لأن المتصفح يحتوي الآن على ملف تعريف ارتباط جلسة صالح (session cookie)، مما يلغي الحاجة إلى إعادة التوجيه إلى نطاق SSO.

هل هناك أي إجراء يمكنني اتخاذه لحل هذه المشكلة بشكل صحيح؟ حاليًا، لدي حل مؤقت فظيع للغاية، يحاول أولاً تحميل موضوع المنتدى في إطار مخفي، ثم ينتظر ثانية واحدة قبل تحميل الموضوع فعليًا في الصفحة المرئية للمستخدم.

أي مساعدة أو اقتراحات ستكون موضع تقدير!

بعد البحث أكثر قليلاً، أتساءل ما إذا كان حل أقل “تلاعباً” قليلاً هو تكييف المنهجية التي وصفها @simon في هذا المنشور: Automatically login via SSO - #4 by simon

  1. تفعيل إعداد “السماح لجميع مسارات العودة عبر SSO”.
  2. إضافة إطار iframe مخفي في صفحتي، يقوم بتحميل https://discourse.example.com/session/sso?return_path=path_to_mypage.html.
  3. عندما يكون المستخدم مسجلاً الدخول (بدون تفاعل، حيث أن المستخدم قد سجّل الدخول بالفعل عبر SSO إلى التطبيق في الصفحة الأصلية) ويتم إعادة توجيه الـ iframe إلى mypage.html، يمكنه التواصل مع الصفحة الأصلية عبر postMessage() للإبلاغ بأن المستخدم قد سجّل الدخول إلى Discourse، مما يؤدي إلى تشغيل السكربت المدمج للموضوع في المنتدى.

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

يبدو لي أن الحل المثالي سيكون إذا كان من الممكن somehow الحفاظ على عنوان URL المرجعي للصفحة المضمنة عند إعادة توجيهها عبر SSO.

تعديل: قمت بتنفيذ “الحيلة” المحسّنة الموصوفة أعلاه في هذا المنشور، وعلى الأقل يمكنني القول إنها تعمل بشكل أفضل بكثير من الحيلة الأصلية التي وصفتها في المنشور الأصلي.