7

私のアプリでは、HTTPS を介して Web サービスへの HTTP 呼び出しを行います。私の望みは、認証チャレンジがある場合にのみユーザーにユーザー名とパスワードを要求するようにクライアントを設計することです。プリエンプティブではなく、リアクティブになりたい。アプリの性質上、認証が不要な場合があります。

iOS では、このプロセスは、私のアプリの iOS バージョンに実装されているNSURLConnectionDelegateProtocolを介して非常に簡単になります。このクラスを使用して接続が確立され、チャレンジが提示された場合にのみ、クラスはデリゲートに認証資格情報を要求します。

Androidでこれを行うにはどうすればよいですか? AuthenticationHandlerを使用していますか? それともオーセンティケーター?もしそうなら、例やチュートリアルを提供できますか?

編集1

Authenticator クラスを使用して (以下の私の回答を参照)、認証の課題に対応できるようになりましたが、現在はハードコードされた資格情報のみを使用しています。ユーザーにユーザー名とパスワードの入力を求めたい。Androidのドキュメントによると、メソッド内でgetPasswordAuthentication「通常、ユーザーに必要な入力を求める」.

これはどのように可能ですか?UI スレッドをブロックせずに、実行できない/すべきではないことがわかっている場合、ダイアログを表示し、ユーザー入力を待ち、入力された資格情報を取得して返すには、すべてそのメソッド内で行うことができますか?

編集2

Authenticator クラスの使用例はほとんどまたはまったくありませんが、私が見つけたものは、getPasswordAuthentication. Apache Http クライアントに戻す必要があるかもしれません...

最終編集:

私はまだ HttpURLConnection を使用していますが、エドワードが以下に提案したことに沿って何かをしています。認証チャレンジを処理し、ユーザーに入力を求めるための構成可能なクラスがないように見えるので、手動でこれを行っています。

4

2 に答える 2

4

認証ヘッダーなしでリクエストを送信します。認証が必要な場合、接続は 401 エラーで失敗します。その失敗の泡が、最初の要求を行ったコードに戻ります。そのコードは、認証ダイアログをユーザーに表示する必要があります。ユーザーが提供するユーザー名/パスワードを記憶し、必要な認証ヘッダーをリクエストに追加して、失敗したリクエストを再試行します。

セッションの残りの部分でユーザー名とパスワードを覚えておくと、ユーザーに何度も尋ねる必要がなくなります。

サンプル コードがなくて申し訳ありません。私はこれを java.net に実装しましたが、Apache を使用している場合は何の役にも立ちません。

このスレッドはあなたを助けるかもしれません: HttpClient を使用して Java での Http 基本認証?

編集:

これを java.net に実装しましたが、これは私が雇った仕事であり、ソース コードにアクセスできません。問題の 1 つは、java.net では接続ごとに認証を設定できず、代わりに単一のグローバル認証システムを実装しなければならないことです。私のアプリは 1 つの特定の Web サイトとしか通信していなかったので、それは問題ではありませんでした。

私がしたことは、ユーザーからのユーザー名/パスワード データをキャッシュするAuthenticatorのサブクラスを作成することでした。キャッシュの初期値は空でした。「お試しカウンター」もあります。オーセンティケータが呼び出され、キャッシュされたユーザー/パスワード情報がない場合、ダイアログでユーザーにプロンプ​​トが表示されます。キャッシュされた値が存在する場合、それらはユーザーを煩わせることなく返されます。

オーセンティケーターへの後続の呼び出しがある場合、ユーザー/パスワード情報が正しくないと見なされ、ユーザーに再度プロンプトが表示されます。カウンターが 10 に達すると、オーセンティケーターは null (失敗) を返します。

カウンターは、新しいインターネット接続のたびにリセットされます。

よりスマートなオーセンティケーターは、ホストやレルム (プロンプト文字列) に注意を払い、それに応じてユーザー/パスワードをキャッシュします。

ダイアログのポップアップはオーセンティケータで利用できない可能性があるため、これが Android 環境で役立つかどうかはわかりません。しかし、私はそれについて間違っている可能性があります。アプリケーションによって異なります。

Android 環境では、スレッドから http リクエストを実行し、データが到着したときにアクティビティを通知する必要があります。スレッドが 401 エラーを検出すると、アクティビティにその影響を通知し、アクティビティがダイアログをポップアップしてスレッドを再起動する可能性があります。次に、スレッドは、ユーザー/パスワード情報を返すだけの簡単なオーセンティケーターを登録します。別の方法として、スレッドで Authorization ヘッダーを手動で作成することもできますが、これは手間がかかります。

于 2012-11-30T00:29:32.583 に答える
3

知らない人のために、Androidで使用できる2つの主要なHttpクライアントAPIがあります。

  • ApacheHTTPクライアント
  • java.net HttpURLConnection

これらの両方の最近の概要は、このAndroidDevelopersブログの投稿に記載されています。

ブログを引用して、java.net実装を使用することを選択しました。「新しいアプリケーションは、HttpURLConnectionを使用する必要があります。これは、今後エネルギーを費やす場所です。」また、URLが提供されている場合、HttpURLConnectionはSSLを使用して自動的に接続します。 Httpsです。元の投稿で述べたように、必要に応じて認証の課題を自動的に処理できるAPI内のインターフェースを探していました。Authenticatorクラスが私が望むことを実行することがわかりました。

これが私がこれまでに持っているコードであり、それは機能します:

URL Url = new URL(url);

Authenticator.setDefault(new Authenticator () {
    protected PasswordAuthentication getPasswordAuthentication() {
        return (new PasswordAuthentication("username", "password".toCharArray()));
    }
});

connection = (HttpURLConnection) Url.openConnection();
connection.setRequestProperty("Authorization", "Basic");

content = new BufferedInputStream(connection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
    stringBuilder.append(line);
}

オーセンティケーターのメソッドを実際に呼び出すための(私にとっての)鍵は、次の行でした。

connection.setRequestProperty("Authorization", "Basic");

それ以外の場合、リクエストは実際には200(OK)の応答を返し、ログインページにリダイレクトします。

次のステップgetPasswordAuthentication上記の方法から、ユーザーにユーザー名とパスワードの入力を求め、なんらかの方法でそれを返します。あなたがこれを手伝うことができるならば、答えを投稿してください!

于 2012-11-30T14:52:36.623 に答える