身份验证错误:无法应对任何这些挑战:{} Android - 401 Unauthorized
我已从此链接中参考 Authentication Error when using HttpPost with DefaultHttpClient on Android
我正在使用Drupal支持的Android应用程序。在那里我将数据从Android应用程序发送到drupal网站 - 以JSON格式的webservice。现在我可以从Drupal webservice读取JSON数据并将其写入我的android应用程序中。但是面对来自android的drupal的写作问题,它会生成状态代码
的响应401未经授权
从Android原生应用程序生成401,而来自phonegap - 来自android,当我启动AJAX请求时,它完美地运行&在drupal网站上写一篇文章或页面。这意味着网络服务工作完美无缺;
我的phonegap Android应用程序完美运行Android本机JAVA应用程序存在问题 我在Android2.3.4上运行我的Android应用程序 - >三星Galaxy S Plus - 三星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发来的链接消息。因为他们建议使用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 Team正式停止了对Apache httpclient的支持。
通过此链接可以解决。我没有尝试过,但我正在努力。
这个库可以帮助升级Android中的httpclient版本。
另一个解决方案可能是使用 HttpURLConnection 。我也在努力。
但是大多数人在stackoverflow和互联网上似乎使用 DefaultHttpCLient 与Android。当然,它也在我的应用程序中与我合作,包括登录,注册,从服务器和会话阅读和其他功能。只是它不能直接发布一些文章到我的服务器-Drupal网站。 在服务器上注册用户期间,它与POST请求完美配合。
所以朋友,对此有何建议?为什么它只是发布文章?
答案 0 :(得分:2)
如何使用PhoneGap,而不是Java。 PhoneGap在Web容器中运行应用程序,因此已经过身份验证 - 并且您拥有所有正确的cookie。 AJAX将分享相同的会话以及“正常工作”。
然而,HTTPClient完全不同 - 您正在启动一个全新的HTTP会话,一切都必须正确。
关于HTTP Auth如何工作的一些评论:
有几种HTTP身份验证方法 - 它是选择哪种方式的Web服务器。在继续之前,请检查您的Drupal配置以确定它是否:
(另请注意,Web容器具有'智能',可以根据服务器的请求尝试不同的身份验证方法,所有这些都在后台进行)
同时检查Drupal网络日志。一些指示:
如果这有帮助,请告诉我。如果没有,并且您可以根据这篇文章提供更多详细信息,我可以提供更多建议。
答案 1 :(得分:1)
您可以尝试检查:How to do http post using apache httpclient with web authentication?
在需要时使用HttpInterceptor
注入身份验证数据
答案 2 :(得分: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标头中添加令牌的类型,这样更容易在飞行中做成。)
一旦一切按预期工作,在您的客户端重现相同的通话,标题和正文,您就可以开始了。
答案 3 :(得分:1)
我遇到了相同的“DefaultRequestDirector:身份验证错误:无法应对任何这些挑战:{}”使用loopj android-async-http library的Drupal服务出现问题(强烈建议)。
解决方案的关键在于Jose L Ugia在关于特别关注Drupal的JSON输出的答案之一中的评论。我试图捕获一个JSONObject,但真正的消息是数组格式“[”错误的用户名或密码。“]”。切换到JSONArray正确捕获了错误并允许我处理它。在您的情况下,我认为这是因为您没有发布登录凭据,因为drupal服务期望它。
你应该记得使用Drupal Services你应该进行系统/连接并获取会话,然后是用户/登录(以及作为参数传入的用户/密码)并获取会话,然后所有后续请求都应该有效。这就是我喜欢使用loopj库的原因,因为它使所有这些请求更易于管理。这是一个用loopj连接到drupal的一个非常基本的例子。所有后续帖子都可以使用参数轻松完成。
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");
}
});
}