2012-08-09 1 views
11

驗證錯誤:無法對任何的應對這些挑戰:{} Android的 - 從這個鏈接401未授權驗證錯誤:無法對任何的應對這些挑戰:{}的Android - 401未授權

我已經採取了參考 Authentication Error when using HttpPost with DefaultHttpClient on Android

我正在使用支持Drupal的Android應用程序。在這我發送數據從Android應用程序到Drupal網站 - JSON格式的Web服務。現在我可以從Drupal web服務中讀取JSON數據並將其寫入我的android應用程序中。但是,在從機器人的Drupal寫面臨的問題,它產生響應的狀態代碼:

401 Unauthorized

從中可以產生401 Android原生應用程序,而來自PhoneGap的,從機器人,當我發起AJAX請求,它完美&寫文章或在Drupal網站上的頁面。這樣就意味着Web服務的工作完全&

my phonegap android app works perfectly there is problem with Android native JAVA application I am running my android application on Android2.3.4 -> 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 =============>  [email protected] 
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上搜索並找到了一些有趣的東西。

1st我發現Android-Google的東西正式不推薦我在我的代碼中使用的Apache HttpClient。檢查這個鏈接。來自Dalvik團隊的傑西威爾遜的Link消息。因爲他們建議使用HttpURLConnection而不是DefaultHttpClient,並且寫道Android團隊將不再開發Apache httpclient。所以它是我正在使用的舊版本。

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

第二的事情,我已經找到形式此鏈接。它表明,Android在發佈Apache的HttpClient 4.0 Beta2時,它有一個陷阱,當談到基本認證。我使用的身份驗證方法是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/

Apache HttpClient 4.1 on Android

What version of Apache HTTP Client is bundled in Android 1.6?

從這些鏈接,我做了一個結論,即如果我們在Apache的HttpClient升級到最新的穩定版本,那麼這個問題就可以解決了。

但是這是不可能的,因爲Android團隊已經正式停止了對Apache httpclient的支持。

有了這個鏈接它可以解決。我沒有嘗試過,但我正在努力。

這是一個庫,可以幫助在Android中升級httpclient版本。

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

另一種解決方案可以使用HttpURLConnection的。我自己也是努力。

但是,大多數人在這裏的stackoverflow和互聯網似乎使用Android的DefaultHttpCLient。當然它也在我的整個應用程序中與我一起工作,包括登錄,註冊,從服務器讀取和會話等功能。只是它不直接將一些文章發佈到我的服務器Drupal網站。 它在服務器上的用戶註冊期間與POST請求完美協作。

那麼朋友們,對此有何建議?爲什麼它不僅僅是發佈文章?

+0

我也看到了這個問題http://stackoverflow.com/questions/10407547/error-http-1-1-401-unauthorized-with-basic-authentication-in-android-ews-201? rq = 1&在我的代碼中嘗試了它...通過用戶名和密碼,但它仍然不起作用。仍然是相同的響應 - > 401 – 2012-08-09 08:17:35

+0

嘗試http:// stackoverflow。com/questions/8022800/problems-doing-ajax-requests-with-a-phonegap-application – 2012-08-09 10:25:09

+0

@ChanchalShelar我沒有遇到PhoneGap的問題......它完美地工作......我有Android Java應用程序的問題。所以在這裏我的問題是:相同的服務器與Phonegap協同工作,那麼爲什麼它不適用於Android。 – 2012-08-09 10:28:44

回答

1

您可以嘗試檢查:How to do http post using apache httpclient with web authentication?

它採用了HttpInterceptor需要時

+0

讓我試試吧。然後我會在這裏更新信息。謝謝。 – 2012-08-09 10:31:14

+1

嗨,我已經嘗試過與該鏈接中提到的HttpRequestInterceptor解決方案。但現在我得到這個錯誤「身份驗證錯誤:預期的基本授權挑戰,但沒有找到」...任何解決方案呢? – 2012-08-09 11:34:01

2

爲什麼它從PhoneGap的,但不是Java的作品注入驗證數據。 PhoneGap在Web容器中運行應用程序,因此已經通過身份驗證 - 並且您擁有所有正確的Cookie。 AJAX將共享相同的會話,並且一切都「正常」。

但HTTPClient是一個完全不同的 - 你正在發起一個全新的HTTP會話,一切都必須是正確的。

上驗證如何HTTP工作的幾點意見:

有幾種HTTP認證方法 - 這是該選擇哪個Web服務器。在繼續之前,請檢查您的Drupal配置以確定它是否爲:

(還要注意的是,Web容器具有「智慧」,能夠嘗試不同的認證方法由服務器的要求,所有在幕後)

同時檢查Drupal的網絡日誌。幾點:

  • 您是否看到HTTPClient連接在所有。並且URL是正確的資源。從服務器的角度來看,總是值得檢查 ...
  • 它是否轉到了正確的服務器?可能出現什麼問題的一個例子:您是否在URL中使用IP 地址來對付多宿主Web服務器,因此請求會發送到錯誤的服務器?
  • 檢查通過先發制人的客戶端發送的驗證是正確的類型(基本,摘要,NTLM)

讓我知道,如果這有助於。如果沒有,並且你可以根據這篇文章提供更多的細節,我可以跟進更多的建議。

+0

嗨安德魯謝謝你的回覆。請檢查我編輯過的問題。我在Google上搜索過,發現了一些有趣的東西。是的,我檢查了服務器日誌,HttpClient與服務器連接。 – 2012-08-18 08:16:04

+1

太好了。我閱讀了這些回覆。大部分問題和錯誤似乎都與Android 1.5和1.6有關 - 你在2.3上比其他版本更好。你有服務器看到的請求的HTTP日誌嗎?你有沒有嗅探連接,並檢查究竟是哪裏出了問題,例如:使用wireshark或Fiddler:http://stackoverflow.com/questions/4853094/best-way-to-analyze-http-traffic-sent-by-my- java-code – 2012-08-19 06:12:54

+0

這也是一篇有用的文章,雖然針對iOS:http://www.tuaw.com/2011/02/21/how-to-inspect-ioss-http-traffic-without-spending-a- dime/ – 2012-08-19 06:14:30

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頭文件中添加令牌類型,並且更容易被製作)。

一旦一切按預期工作,在您的客戶端重現相同的呼叫,標題和正文,您就可以開始了。

+1

要特別注意JSON嵌套和數組。一些服務不支持(或期待)只是一種請求。 (即:使用對象而不是數組類型的屬性名稱 - >「provider [0]」:「DHL」等)。 – 2012-08-18 08:50:38

+0

嗨,何塞,謝謝你的回覆。 PHP端我使用的是Drupal。按照您的建議,我可以使用poster firefox插件來測試我的服務和JSON對象或數組。 https://addons.mozilla.org/en-US/firefox/addon/poster/讓我試試看,然後我會再次給你發消息。謝謝。 – 2012-08-18 09:04:21

1

我遇到了與使用loopj android-async-http library(極力推薦它)的Drupal服務相同的「DefaultRequestDirector:身份驗證錯誤:無法應對以下任何挑戰:{}」問題。{}

解決方案的關鍵在於Jose L Ugia在關於特別關注Drupal的JSON輸出的答案之一中的評論。我試圖抓住一個JSONObject,但真正的消息是數組格式「[」錯誤的用戶名或密碼。「]」。切換到JSONArray正確捕獲錯誤,並允許我處理它。在你的情況下,我相信這是因爲你不會像drupal服務所期望的那樣發佈登錄憑證。

你應該記得在Drupal服務中你應該做系統/連接並獲取會話,然後是用戶/登錄(並將用戶/密碼作爲參數傳入)並獲取會話,然後所有後續請求都可以工作。這就是爲什麼我喜歡使用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"); 
     } 
    }); 
    }