12

認証エラー: 次のチャレンジのいずれにも応答できません: {} Android - 401 Unauthorized

Android で DefaultHttpClient を使用して HttpPost を使用する場合、このリンク認証エラーから参照し ました。

私は Drupal に裏打ちされた Android アプリに取り組んでいます。その中で、Androidアプリからdrupal Webサイト(JSON形式のWebサービス)にデータを送信しています。これで、Drupal Web サービスから JSON データを読み取って、Android アプリケーションに書き込むことができます。しかし、android から drupal への書き込みで問題が発生し、ステータス コードで応答が生成されます。

401無許可

Androidネイティブアプリからは 401 が生成されますが、phonegap-from AndroidからはAJAXリクエストを開始すると完全に機能し、drupal Webサイトに記事またはページが書き込まれます。つまり、Webサービスは完全に機能します &

私のphonegap Androidアプリは完全に動作しますAndroidネイティブJAVAアプリケーションに問題がありますAndroid2.3.4でAndroidアプリケーションを実行しています-> Samsung Galaxy S Plus-Samsung GT-I9001

これがJava Androidの私のコードです。

==============================

String url = "XXX";
strResponse1 = makeWebForPostIdea(url,title,body);

public static String makeWebForPostIdea(String url, String title,String body)
    {
        JSONStringer jsonobject = null;
        JSONObject json = null;
        JSONObject jsonnode = null;

        DefaultHttpClient client = new DefaultHttpClient();

Credentials creds = new UsernamePasswordCredentials("username", "password");
        client.getCredentialsProvider().setCredentials(new       AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
 HttpPost post = new HttpPost(url);
System.out.println("value of the post =============> "+post);
 try {
            JSONObject jsonvalue = new JSONObject();
            jsonvalue.put("value", body.toString());

            JSONArray array = new JSONArray();
            array.put(jsonvalue);

            jsonnode = new JSONObject();
            jsonnode.put("und", array);

            System.out.println("@@@@@@2    jsonnode=======>"+jsonnode.toString());


        } catch (JSONException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }
 try {
 jsonobject = new JSONStringer().array().object().key("und").object().key("0").object().key("value").value(body).endObject().endObject().endObject().endArray();
    System.out.println("=============>"+jsonobject);

        } catch (JSONException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }

         List<NameValuePair> params = new ArrayList<NameValuePair>();

                 params.add(new BasicNameValuePair("type","page"));

            params.add(new BasicNameValuePair("title",title));
            params.add(new BasicNameValuePair("language","und"));
            params.add(new BasicNameValuePair("body",jsonobject.toString()));

            System.out.println("value of the params =============> "+params);

        UrlEncodedFormEntity formEntity = null;
        try {
                formEntity = new UrlEncodedFormEntity(params);
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        post.setEntity(formEntity);

        try {

            HttpResponse response = client.execute(post);

            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("=========> statusCode post idea=====> "+statusCode);    
            if (statusCode == HttpStatus.SC_OK)
            {
                HttpEntity entity = response.getEntity();
                InputStream is = entity.getContent();
                return iStream_to_String(is);
            }
            else
            {
                return "Hello This is status ==> :"+String.valueOf(statusCode);
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

     public static String iStream_to_String(InputStream is1) {
            BufferedReader rd = new BufferedReader(new InputStreamReader(is1), 4096);
            String line;
            StringBuilder sb = new StringBuilder();
            try {
                while ((line = rd.readLine()) != null) {
                    sb.append(line);
                }
                rd.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String contentOfMyInputStream = sb.toString();
        return contentOfMyInputStream;
            }

    }

   }

ここに私が得ているlogcatがあります。

 08-09 12:41:29.063: I/System.out(336): value of the post =============>      org.apache.http.client.methods.HttpPost@4053c3c8
 08-09 12:41:29.093: I/System.out(336): @@@@@@2    jsonnode=======>{"und":  [{"value":"ddddddd"}]}
 08-09 12:41:29.093: I/System.out(336): =============>[{"und":{"0":{"value":"ddddddd"}}}]
 08-09 12:41:29.103: I/System.out(336): value of the params =============> [type=page, title=hhhh, language=und, body=[{"und":{"0":{"value":"ddddddd"}}}]]
 08-09 12:41:30.913: W/DefaultRequestDirector(336): Authentication error: Unable to respond to any of these challenges: {}
 08-09 12:41:30.913: I/System.out(336): =========> statusCode post idea=====> 401
 08-09 12:41:30.924: I/System.out(336): =========> Response from post  idea => Hello This is status ==> :401

これが私のPhoneGap Ajaxリクエストで、完全に機能します。

$('#page_node_create_submit').live('click',function(){

  var title = $('#page_node_title').val();
  //if (!title) { alert('Please enter a title.'); return false; }

  var body = $('#page_node_body').val();
  //if (!body) { alert('Please enter a body.'); return false; }

  // BEGIN: drupal services node create login (warning: don't use https if you don't     have ssl setup)
  $.ajax({
      url: "XXX",
      type: 'post',
      data: 'node[type]=page&node[title]=' + encodeURIComponent(title) +  '&node[language]=und&node[body][und][0][value]=' + encodeURIComponent(body),
      dataType: 'json',
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('page_node_create_submit - failed to login');
        console.log(JSON.stringify(XMLHttpRequest));
        console.log(JSON.stringify(textStatus));
        console.log(JSON.stringify(errorThrown));
      },
      success: function (data) {
      $.mobile.changePage("index.html", "slideup");
     }
  });
  // END: drupal services node create

  return false;

});

================================================== ===============================

編集 :

エラーに対して Apache httpclient のさまざまな方法を試しました。この間、いくつかの調査を行い、Google で検索したところ、興味深いことがわかりました。

Android-Google は、コードで使用している Apache HttpClientを公式に推奨していないことがわかりました。このリンクを確認してください。Dalvik チームの Jesse Wilson からのリンク メッセージ。彼らは DefaultHttpClient の代わりに HttpURLConnection を使用することを提案し、Android チームは Apache httpclient を開発しなくなるとも書いています。そのため、私が使用している古いバージョンです。

http://android-developers.blogspot.in/2011/09/androids-http-clients.html

このリンクから見つけた2番目のもの。基本認証に関しては、落とし穴がある Apache の HttpClient 4.0 Beta2 が Android に同梱されていることを示唆してい ます。 私が使用している認証方法は、このリンクから見つけた HttpClient 3.x のものです。リンクを確認してください。 http://hc.apache.org/httpclient-3.x/authentication.html#Preemptive_Authentication

というわけでバージョンの問題。

http://dlinsin.blogspot.in/2009/08/http-basic-authentication-with-android.html

この問題の潜在的な解決策へのリンクもいくつか見つけました。

http://ogrelab.ikratko.com/using-newer-version-of-httpclient-like-4-1-x/

Android 上の Apache HttpClient 4.1

Android 1.6 にバンドルされている Apache HTTP クライアントのバージョンは何ですか?

これらのリンクから、Apache HttpClient を最新の安定バージョンにアップグレードすれば、この問題は解決できるという結論に達しました。

しかし、Android チームが Apache httpclient のサポートを正式に停止したため、これは直接的には不可能です。

このリンクで解決できる可能性があります。私はそれを試していませんが、私はそれに取り組んでいます。

Android の httpclient バージョンをアップグレードするのに役立つライブラリです。

http://code.google.com/p/httpclientandroidlib/

他の解決策はHttpURLConnectionを使用することです。私もそれに取り組んでいます。

しかし、stackoverflow とインターネットのほとんどの人は、Android でDefaultHttpCLientを使用しているようです。そしてもちろん、ログイン、登録、サーバーとセッションからの読み取り、その他の機能を含むアプリケーション全体で私と一緒に働いています.ちょうどそれは私のサーバー-Drupal Webサイトに記事を直接投稿することでは機能していません. サーバーにユーザーを登録する際の POST リクエストと完全に連携します。

友達、これに関する提案はありますか?記事を投稿するだけで機能しないのはなぜですか?

4

4 に答える 4

2

PhoneGap では機能するのに、Java では機能しないのはなぜですか。PhoneGap は Web コンテナーでアプリを実行するため、既に認証されており、すべての適切な Cookie があります。AJAX は同じセッションを共有し、すべてが「正常に動作」します。

ただし、HTTPClient はまったく異なります。まったく新しい HTTP セッションを開始しており、すべてが正しくなければなりません。

HTTP Auth の仕組みに関するいくつかのコメント:

いくつかの HTTP 認証方法があり、どれを選択するかは Web サーバーです。先に進む前に、Drupal 構成をチェックして、次のようになっているかどうかを確認してください。

  • 基本認証 (ユーザー名とパスワード)。誰もがこれをサポートしていますが、非常に安全ではありません。詳細については、 http://en.wikipedia.org/wiki/Basic_access_authenticationを参照してください
  • ダイジェスト (ユーザー名と MD5 によるチャレンジ/レスポンス ハッシュ。これはより安全ですが、はるかに複雑です。現在、MD5 は一般的に弱いと見なされていることに注意してください。Apache を含む多くのライブラリがサポートしています。http://en.wikipedia.org/wiki/を参照してください。詳しくはDigest_access_authentication
  • IIS に実装されている NTLM (Kerberos/SPEGNO のバリアント)。HTTPClient は公言していますが、これは Java からは一般的にサポートされていませんが、別の Credentials オブジェクトを使用しています。http://hc.apache.org/httpclient-3.x/authentication.html#NTLMを参照してください

(Web コンテナーには、サーバーからの要求に応じてさまざまな認証方法をすべて舞台裏で試すことができる「スマート」があることにも注意してください)

Drupal の Web ログも確認してください。いくつかの指針:

  • HTTPClientがまったく接続されているのを見ましたか。また、URL は正しいリソースに移動していますか。サーバーの観点から常にチェックする価値があります...
  • 正しいサーバーに移動しましたか? 問題が発生する可能性のある例: マルチホーム Web サーバーに対する URL で IP アドレスを使用しているため、要求が間違ったサーバーに送られますか?
  • クライアントからプリエンプティブに送信された認証が正しいタイプ (基本、ダイジェスト、NTLM) であることを確認します。

これが役立つかどうか教えてください。そうでない場合は、この投稿に従って詳細を提供していただければ、さらにアドバイスを提供できます。

于 2012-08-15T06:03:21.447 に答える
1

以下を確認してみてください: How to do http post using apache httpclient with web authentication?

必要に応じて、 を使用しHttpInterceptorて認証データを挿入します。

于 2012-08-09T10:25:50.817 に答える
1

最初にアプリの PHP 側をテストすることをお勧めします。ヘッダーや認証など、独自の呼び出しを行う方法はいくつかあります。curl から GraphicalHttpClient (http://itunes.apple.com/us/app/graphicalhttpclient/id433095876?mt=12 、私は個人的にそれを使用しており、適切に動作します)。REST クライアント デバッガー (https://addons.mozilla.org/en-US/firefox/addon/restclient/) のような他のいくつかのオプションがあります。

このようにして、非常に多くの方法で呼び出しをテストできますが、クライアントで直接行うのは面倒です (http から https に変更したり、Authorization ヘッダーにトークンのタイプを追加したりするだけで、はるかに簡単に作成できます)。ハエ)。

すべてが期待どおりに機能したら、クライアントで同じ呼び出し、ヘッダー、および本文を再現すれば、準備完了です。

于 2012-08-18T08:47:13.777 に答える
1

loopj android-async-http ライブラリを使用する Drupal サービスで、同じ「DefaultRequestDirector: 認証エラー: これらの課題のいずれにも応答できません: {}」という問題が発生しました(強くお勧めします)。

私にとっての解決策の鍵は、Drupal からの JSON 出力に特別な注意を払うことに関する回答の 1 つである Jose L Ugia のコメントにありました。JSONObject をキャッチしようとしましたが、実際のメッセージは "["ユーザー名またはパスワードが間違っています。"]" という配列形式でした。JSONArray に切り替えると、エラーが適切にキャッチされ、処理できるようになりました。あなたの場合、drupalサービスが期待するようにログイン資格情報を投稿していないためだと思います。

Drupal サービスでは、system/connect を実行してセッションを取得し、その後に user/login (およびパラメーターとして渡されたユーザー/パスワード) を実行してセッションを取得し、その後のすべてのリクエストが機能することを覚えておく必要があります。これが、これらすべての要求をより管理しやすくする loopj ライブラリを使用するのが好きな理由です。これは、loopj を使用して drupal に接続する非常に基本的な例です。以降のすべての投稿は、params を使用して簡単に行うことができます。

public class Loopj {
  private static final String TAG = "loopj";

  private static AsyncHttpClient client = new AsyncHttpClient();
  private final PersistentCookieStore myCookieStore;


  public Loopj(Context context) {
    myCookieStore = new PersistentCookieStore(context);
    client.setCookieStore(myCookieStore);
    client.addHeader("Content-type", "application/json");
  }


  public void systemConnect(String uri) throws JSONException {
    client.post(uri + "/endpoint/system/connect", new JsonHttpResponseHandler() {
      @Override
      public void onSuccess(JSONObject json) {
        Log.i("TAG", "Connect success =" + json.toString());
      }

      @Override
      public void onFailure(Throwable e, String response) {
        Log.e("TAG", "Connect failure");
      }
    });
  }

  public void userLogin(String uri) throws JSONException {
    RequestParams params = new RequestParams();
    params.put("username", username);
    params.put("password", password);
    client.post(uri + "/endpoint/user/login", params, new JsonHttpResponseHandler() {
      @Override
      public void onSuccess(JSONArray response) {
        Log.i("TAG", "Login success =" + response.toString());
      }

      @Override
      public void onFailure(Throwable e, JSONArray json) {
        Log.e("TAG", "Login failure");
      }
    });
  }
于 2012-08-23T17:12:15.480 に答える