مرحبًا! لقد قمنا بكتابة مكوّن إضافي مخصص لـ SSO لتجميع تفاصيل تسجيل الدخول الخاصة بشركتنا في حزمة يمكن لـ Discourse استخدامها للتعامل مع تسجيل الدخول وإنشاء الحسابات. مع الإصدار v2.7.0beta4، بدأنا في تلقي أخطاء تشير إلى أننا لم نوفر معلمة جديدة، وهي secure_session. لا أستطيع العثور على أي تفاصيل حول تنسيق هذه المعلمة أو ما يجب أن تحتويه. هل هناك أي توثيق إضافي متاح لهذا التحديث؟
هل تعرف الرسالة الدقيقة للخطأ التي تظهر؟ فهمي هو أن نظام Discourse يربط الآن معلمة nonce الخاصة بـ SSO بجلسة المستخدم. هذا يعني أنه إذا كان التطبيق يولد nonce عن طريق إجراء طلب في الخلفية إلى /session/sso، فإن قيمة nonce لن تكون صالحة. ربما هذه هي المشكلة التي تواجهها.
ملف service_gateway_current_user.rb هو جزء من الإضافة (plugin) الخاصة بنا لبناء الحمولة (payload) المرسلة إلى DiscourseSingleSignOn بناءً على رؤوس “بوابة الخدمة” (Service Gateway) — وهي البنية الداخلية لشركتنا لتحديد ما إذا كنت قد قمت بتسجيل الدخول إلى نظامنا.
لتوضيح تلك الجزء من المكدس:
دالة current_user الخاصة بنا تستخدم الرؤوس للبحث عن سجل SingleSignOnRecord حيث يتطابق external_id مع معرف المستخدم في الرؤوس. إذا لم يكن الأمر كذلك، ننتقل إلى قسم create_sso_record.
تقوم create_sso_record بإنشاء هاش — { external_id: sg_headers[:user_id], email: sg_headers[:email] } — وترسله إلى دالة upsert_sso_record الخاصة بنا.
تأخذ upsert_sso_record ذلك الهاش (المُشار إليه بـ payload في السياق أدناه) وتحاول إنشاء كائن DiscourseSingleSignOn:
def upsert_sso_record(payload)
encoded_query = Base64.encode64(payload.to_query)
sig = OpenSSL::HMAC.hexdigest('sha256', ENV['SSO_SECRET'], encoded_query)
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query)
if SiteSetting.verbose_sso_logging
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
Rails.logger.warn("SSO Payload:\n\n#{payload}")
end
begin
user = sso.lookup_or_create_user(@request.ip)
rescue ActiveRecord::RecordInvalid => ex
Rails.logger.error "Unable to find/create sso user #{ex}"
end
user
end
يبدو أن استدعاء parse في السطر الثالث من تلك الدالة هو المكان الذي تنشأ فيه المشكلة. بمجرد محاولة تهيئة الكائن، فإن قيمة secure_session المتوقعة غير موجودة.
أتساءل عما إذا كان تعيين إعداد الموقع الجديد discourse_connect_csrf_protection إلى false سيحل المشكلة لديك. هذا الإعداد مخفي، لذا يجب تعيينه من وحدة تحكم Rails. يمكنك العثور على التفاصيل المتعلقة به في الردود على هذا الموضوع: DiscourseConnect flow no longer functions.
من الصعب التأكد من ذلك دون رؤية الإضافة بالكامل، لكن يمكنك تجربة تمرير قيمة nil لـ secure_session. قد يساعد ذلك، إلى جانب تفعيل إعداد الموقع الجديد، في تقريب الأمور قليلاً من العمل بشكل صحيح.
بعد الغوص أكثر في كود v2.7.0.beta4، أرى أن ApplicationController يحتوي على تعريف secure_session. يبدو أن تغيير كود الإضافة لدينا إلى ما يلي يعمل في بيئة الاختبار (Staging):
sso = DiscourseSingleSignOn.parse({ sso: encoded_query, sig: sig }.to_query, secure_session: secure_session)