2

Webサイトから認証を受けようとしています。私はを使用してAsyncHttpClientいます。これが私が試しているコードです。

これが私のコードです、

public class LoginActivity extends Activity {

    String tag = "LoginActivity";
    Button requestBtn;
    AsyncHttpClient httpClient = new AsyncHttpClient();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        requestBtn = (Button) findViewById(R.id.upload_file);

        PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
        httpClient.setCookieStore(myCookieStore);

        httpClient.setBasicAuth(ApplicationConstants.userName,
                ApplicationConstants.password, new AuthScope(
                        "http://*.*.*.*:8080/someUrl", 8080,
                        AuthScope.ANY_REALM));




        requestBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
      httpClient.get("http://*.*.*.*:8080/someurl",new AsyncHttpResponseHandler() {

                @Override
                public void onSuccess(String response) {
                System.out.println(response);
                Log.d("Sucessful upload","Onsucess" + response);
                }

                @Override
                public void onFailure(Throwable arg0,String arg1) {

                Log.d("LoginActivity",arg0.toString());
                arg0.printStackTrace();
                super.onFailure(arg0, arg1);
                }
            });
        }

    }
    });
}
}

ボタンをタップすると例外が発生します。認証に失敗したという例外ログキャット:

02-27 16:02:42.930: D/LoginActivity(8869): org.apache.http.client.HttpResponseException: Unauthorized
02-27 16:02:42.930: W/System.err(8869): org.apache.http.client.HttpResponseException: Unauthorized
02-27 16:02:42.930: W/System.err(8869):     at com.loopj.android.http.AsyncHttpResponseHandler.sendResponseMessage(AsyncHttpResponseHandler.java:235)
02-27 16:02:42.930: W/System.err(8869):     at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:79)
02-27 16:02:42.930: W/System.err(8869):     at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:95)
02-27 16:02:42.930: W/System.err(8869):     at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:57)
02-27 16:02:42.930: W/System.err(8869):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
02-27 16:02:42.930: W/System.err(8869):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-27 16:02:42.930: W/System.err(8869):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-27 16:02:42.940: W/System.err(8869):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-27 16:02:42.940: W/System.err(8869):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-27 16:02:42.940: W/System.err(8869):     at java.lang.Thread.run(Thread.java:856)

私は何が悪いのですか?私が使用しているURLは正しいです。

4

3 に答える 3

12

setBasicAuth(username, password)上記の提案されたソリューションとAsyncHttpClientのデフォルト(バグのある)実装を使用してAuthorizationヘッダーを構築する方法が気に入らないプロキシ間で問題が発生したため、別のソリューションを思いつきました。

そこで、自分でヘッダーを追加し、BASE64ユーザー名/パスワードのエンコードを自分で行いましたがaddHeader()、親クライアントの実装から継承されたメソッドを使用しました。

今は動作します。

asyncHttpClient.addHeader(
  "Authorization",
    "Basic " + Base64.encodeToString(
      (username+":"+password).getBytes(),Base64.NO_WRAP)
);

これが誰かに役立つことを願っています。

于 2013-12-13T03:50:29.113 に答える
5

Androidでの基本認証から:

Androidには、基本認証に関して落とし穴があるApacheのHttpClient4.0Beta2が同梱されています。

HttpClientと基本認証を検索すると、Googleは間違いなくHttpClient 3.xの公式ドキュメントにあなたを送ります。これは、プリエンプティブな方法で基本認証を行う方法を示しています。つまり、401 Unauthorized応答を待ってから資格情報を送信するのではなく、要求ごとにクライアントの資格情報を送信します。それはあなたのクライアントにリクエストを保存するので、おそらくあなたが最初にやりたいことです。

HttpClient client = new HttpClient();
client.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(new AuthScope("myhost", 80, AuthScope.ANY_REALM), defaultcreds);

このサンプルコードは、HttpClientバージョン4ではコンパイルされません。setAuthenticationPreemptiveというメソッドがありません。問題は、このメソッド呼び出しを省略しても、コードは機能しますが、認証はプリエンプティブではないということです。この小さな詳細を見逃し、しばらくすると、すべての要求の前に401の無許可の要求/応答サイクルが発生することに気づきました。これにより、提供したリクエストの量が2倍になりました。

次に、AsyncHttpClientの実装を確認します。

private final DefaultHttpClient httpClient;
public void setBasicAuth( String user, String pass, AuthScope scope){
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user,pass);
    this.httpClient.getCredentialsProvider().setCredentials(scope, credentials);
}

したがって、loopjは、基本認証を行うための古いHttpClient3.xの方法を使用する際の問題にも遭遇する可能性があると思います。動作しますが、プリエンプティブではありません。

簡単な解決策は、loopjのソースコードをダウンロードしてそのソースを変更し、変更されたバージョンを使用することです。

コードの変更は次のようになります。

    httpClient.setBasicAuth(ApplicationConstants.userName,
            ApplicationConstants.password);

それ以外の

            httpClient.setBasicAuth(ApplicationConstants.userName,
            ApplicationConstants.password, new AuthScope(
                    "http://*.*.*.*:8080/uploadservice", 80,
                    AuthScope.ANY_REALM));
于 2013-02-27T11:44:25.577 に答える
4

基本認証を処理するヘッダーを明示的に追加することで、この問題を解決できると思います。

Context context = this;
String url = "http://*.*.*.*:8080/someurl";

UsernamePasswordCredentials credentials = 
new UsernamePasswordCredentials(ApplicationConstants.userName,
            ApplicationConstants.password);

Header header = BasicScheme.authenticate(credentials, "UTF-8", false);

Header[] headers = {header};

RequestParams params = new RequestParams();

httpClient.get(context, url, headers, params, new AsyncHttpResponseHandler(){ ..

また、サーバーの応答を知りたい場合は、「onComplete」メソッドもオーバーライドすることを忘れないでください。例外の場合、「onSuccess」と「onFailure」を通過しない可能性があるためです。

于 2013-02-27T12:07:08.450 に答える