验证错误:无法对任何的应对这些挑战:{}的Android - 401未授权

问题描述:

验证错误:无法对任何的应对这些挑战:{} 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

您可以尝试检查: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

为什么它从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

我建议首先测试应用程序的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

我遇到了与使用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"); 
     } 
    }); 
    }