7

HTTPダイジェスト認証を使用するサーバーと通信するアプリがあります。

iPhone内の「セッション」管理は、私たちの開発者にとってはかなり「ブラックボックス」のように思えます。フレームワークがhttpセッションをどのように処理/永続化するかがわからないというのは本当ですか?

私がここで薄暗いだけの場合、誰かがiPhoneでHTTPダイジェスト認証を処理する方法を説明してくれるでしょうか?

私の基本的な実行は次のとおりです。

  • 安全なURLにリクエストを送信します
  • サーバーは401を送信します
  • クライアントはクレデンシャルを作成して保持し、それをサーバーに返します
  • サーバーは資格情報を検証し、検証された場合は要求を完了し、検証されなかった場合は別の401を送信します。
  • URLを保護するために後続のリクエストを行います
  • サーバーが再度認証を要求します.......。

これは単一のリクエストで機能しますが、追加の後続のリクエストを行うと、サーバーは再度承認をリクエストします。サーバーは特定のユーザーのセッションを永続化していますが、iPhoneは何らかの理由で同じセッション内で要求を行っていません...したがって、サーバーは認証オブジェクトを破棄し、クライアントごとに新しい認証オブジェクトを作成する必要があります保護されたURLにリクエストを送信します。

これは正しい動作ではないと確信しています。

この状況でブラウザがどのように動作するかを見ると、次のようになります。

  • ブラウザが安全なURLからデータを要求する
  • サーバーは401を送信します
  • ブラウザはユーザーに資格情報の入力を求め、それを保持し、サーバーに渡します
  • サーバーは資格情報を検証し、検証された場合はデータを返し、そうでない場合は別の401を送信します。
  • ブラウザがセッションを管理しているため、URLを保護するために行われた後続の要求では、資格情報の入力は求められません。

NSURLCredentialを作成し、NSURLCrendtialStorage内に永続化しています。次に、アプリが「didReceiveAuthenticationChallenge」を受信すると、ストレージからクレデンシャルを取得して返し、クレデンシャルが存在しない場合は作成します(最初のリクエストで)。

どんな助けでも大歓迎です。ありがとう。

4

2 に答える 2

3

まず、HTTP セッションについては忘れてください。これらは、ダイジェスト認証のアクティブなログインと対話しないためです (一種のセッション情報機能がありますが、それは異なります)。

実際、Digest を使用する主な理由の 1 つは、ログイン状態を維持するためだけにセッションを使用する必要がないことです。セッションは重く、スケーラビリティを損ないます。

あなたの問題が何であるかははっきりとは言えませんが、最初に確認することはわかっています。これは、古くなったものを正しく使用し、ナンスを正しく作成することです。

ユーザーエージェントは、同じナンスを処理するように求められた場合にのみ、ユーザーに再クエリを実行せずに認証を処理できます。別のケースでは、後で説明します (この順序で説明すると簡単です)。

各リクエストで同じナンスが使用されている場合、ユーザーエージェントはユーザー/パスからの「ha1」とともにそれを使用し続け、後続のリソースをリクエストします。これは事前に行われるため、チャレンジは発生しません。

もちろん、同じノンスを使用すると、リプレイ攻撃がトラフィックを盗聴できる人にとっては取るに足らないものになるため、セキュリティの要素が導入されます。ナンスは定期的に変更する必要があります。

したがって、無効な Authorization ヘッダーを持つユーザー エージェントからリクエストを受け取ったが、それが無効である理由がナンスが間違っている (有効期限が切れたものを使用している) 場合、チャレンジに "stale=true" を含めます (デフォルトは間違い)。これは、拒否の理由がナンスが古くなっていることをユーザーエージェントに通知します(もちろん、他の情報も間違っている可能性がありますが、どちらの方法でも再生させないため、それは問題ではありません)。

このような stale=true を受け取ると、ユーザー エージェントはそれが承認されていないことを認識しますが、ユーザーを再クエリする (または UI のないコンポーネントの場合は例外をスローする) 代わりに、新しいナンスで古い基準を再試行します。

これがあなたに影響を与えているかどうかはわかりませんが、ノンスと古さを判断して通知する方法は、確かに私が最初に見たいものです.

于 2010-08-18T11:05:56.447 に答える
1

HTTP認証を使用してiPhoneアプリを作成し、あなたが説明したことを経験しました。(私のアプリケーションでは、ダイジェスト認証の代わりに基本認証を使用していますが、ここでは大きな違いはありません。)

不具合の原因はiPhone側にあります。iPhone が HTTP 要求ヘッダーで資格情報を送信しない場合、サーバーは 401 で応答する必要があります。実際には、資格情報が資格情報ストレージに格納されると簡単にできるにもかかわらず、そうではありません。

この奇妙な動作は、アプリケーションの速度に深刻な影響を与えました。これは、すべてのリクエストがサーバーへのラウンドトリップを 1 回ではなく 2 回 (最初のラウンドトリップはステータス 401、2 回目のラウンドトリップは 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"];

現在、私のアプリケーションは非常にスムーズに動作し、非常に反応が良いです。

ダイジェスト認証の場合、ソリューションは少し異なります。しかし、あなたはアイデアを得るでしょう。

于 2010-08-11T18:56:46.667 に答える