سؤال

لديّ تطبيق يتواصل مع خادم يستخدم مصادقة HTTP Digest.

يبدو لي أن إدارة "الجلسة" داخل iPhone هي "الصندوق الأسود" إلى حد كبير للمطورين الأمريكيين. هل صحيح أننا لا نستطيع أن نرى كيف يتعامل الإطار / يستمر في جلسات HTTP؟

إذا كنت خافتًا هنا ، فهل يهتم أحدهم بشرح كيفية التعامل مع مصادقة HTTP Digest على iPhone؟

الجري الأساسي الخاص بي هو:

  • تقديم طلب إلى عنوان URL المضمون
  • يرسل الخادم 401
  • يقوم العميل بإنشاء بيانات الاعتماد ويستمر فيها ، وينقلها إلى الخادم
  • يتحقق الخادم من بيانات الاعتماد ، ويكمل الطلب إذا تم التحقق منه ، يرسل 401 آخر إن لم يكن كذلك.
  • تقديم طلب لاحق لتأمين عنوان URL
  • طلبات الخادم ترخيص مرة أخرى ........

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

أنا متأكد من أن هذا ليس سلوكًا صحيحًا.

إذا نظرنا إلى كيفية تصرف المتصفح في هذا الموقف:

  • يطلب المتصفح بيانات من عنوان URL الآمن
  • يرسل الخادم 401
  • يطالب المستعرض المستخدم بملاءمة الاعتماد ، ويستمر في ذلك ، ويمرره إلى الخادم
  • يتحقق الخادم من بيانات الاعتماد ، وإرجاع البيانات إذا تم التحقق منه ، يرسل 401 آخر إن لم يكن.
  • لا يُطلب من الطلبات اللاحقة المقدمة لتأمين عناوين URL لبيانات الاعتماد لأن المتصفح يدير الجلسة.

أقوم بإنشاء NSURLCREDINCITY وأستمر في ذلك داخل NSURLCRendTialStorage. ثم عندما يتلقى التطبيق "didReceiveAuthenticationChallenge" ، أسترجع بيانات الاعتماد من التخزين وأمرها ، وإنشاء بيانات الاعتماد إذا لم تكن موجودة (في الطلب الأول).

أي مساعدة سيكون موضع تقدير كبير. شكرًا.

هل كانت مفيدة؟

المحلول

أول شيء ، هو نسيان جلسات HTTP ، لأن هذه لا تتفاعل مع مصادقة Digest Active Logins (هناك نوع من قدرة معلومات الجلسة ، لكنها مختلفة).

في الواقع ، فإن أحد الأسباب الرئيسية لاستخدام Digest ، هو ألا تضطر إلى استخدام جلسات فقط للحفاظ على حالة تسجيل الدخول. الجلسات ثقيلة وتؤذي التوسع.

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

لا يمكن لمستخدمي المستخدم التعامل مع المصادقة إلا دون طلب المستخدم إذا طُلب منهم التعامل مع نفس NONCE ، أو في حالة أخرى سأصل إليها لاحقًا (أسهل في شرحها بهذا الترتيب).

إذا كان لديك نفس غير مستخدم في كل طلب ، فسيستمر وكيل المستخدم في استخدامه مع "HA1" من المستخدم/التمريرة لطلب الموارد اللاحقة. يتم ذلك بشكل مسبق ، وبالتالي فإن التحدي لا يحدث أبدًا.

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

وبالتالي ، إذا تلقيت طلبًا من وكيل مستخدم برأس ترخيص غير صالح ، ولكن السبب في أنه غير صالح هو أن Nonce خاطئ (فهو يستخدم واحد منتهية الصلاحية) ثم في التحدي الخاص بك يتضمن "Stale = True" ( خاطئة). هذا يخبر وكيل المستخدم أن سبب رفضك هو أن NonCe قديم (بالطبع قد تكون المعلومات الأخرى خاطئة أيضًا ، لكن هذا لا يهم لأنك لن تدعها تلعب في أي من الاتجاهين).

عند استلام مثل هذا القدر = صحيح ، سيعرف وكيل المستخدم أنه غير مصرح به ، ولكن بدلاً من طلب المستخدم (أو إلقاء استثناء إذا كان مكونًا أقل من واجهة المستخدم) ، سيقوم بإعادة محاولة المعايير القديمة مع NONCE الجديد.

لا يمكنني معرفة ما إذا كان أي من هذا هو ما يؤثر عليك ، ولكن الطريقة التي يتم بها تحديد عدم الحالات والطالبة والإشارة إلى أنها بالتأكيد أول شيء أنظر إليه.

نصائح أخرى

لقد كتبت تطبيق iPhone مع مصادقة HTTP وشهدت ما تصفه. (يستخدم طلبي المصادقة الأساسية بدلاً من مصادقة Digest ، لكن هذا لا يحدث فرقًا كبيرًا هنا.)

سبب المشكلة على جانب iPhone. مطلوب الخادم للإجابة باستخدام 401 إذا لم يرسل iPhone بيانات الاعتماد في رأس طلب HTTP. وفي الواقع ، لا يمكن تخزين بيانات الاعتماد بسهولة في تخزين بيانات الاعتماد بسهولة.

كان لهذا السلوك الغريب تأثير شديد على سرعة التطبيق لأن كل طلب تسبب في رحلتان مستديرتين إلى الخادم بدلاً من واحد (الأول مع الحالة 401 ، والثانية مع 200).

لقد قمت بحلها عن طريق ضبط بيانات الاعتماد يدويًا في رأس طلب HTTP:

NSString* credentials = [NSString stringWithFormat: @"%@:%@", usr, pwd];
const char* credentialsChars = [credentials cStringUsingEncoding: NSUTF8StringEncoding];
credentials = [CommunicationUtil stringBase64WithData: (const UInt8*) credentialsChars length: strlen(credentialsChars)];
NSString* authorizationHeader = [NSString stringWithFormat: @"Basic %@", credentials];

NSMutableURLRequest* request =
    [[NSMutableURLRequest alloc] initWithURL: url 
        cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
        timeoutInterval: 15];

    [request setValue: authorizationHeader forHTTPHeaderField: @"Authorization"];

الآن طلبي يعمل بسلاسة شديدة ويستجيب للغاية.

سيبدو الحل مختلفًا قليلاً عن مصادقة Digest. لكن ستحصل على الفكرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top