验证错误:无法对任何的应对这些挑战:{}的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版本。
另一种解决方案可以使用HttpURLConnection的。我自己也是努力。
但是,大多数人在这里的stackoverflow和互联网似乎使用Android的DefaultHttpCLient。当然它也在我的整个应用程序中与我一起工作,包括登录,注册,从服务器读取和会话等功能。只是它不直接将一些文章发布到我的服务器Drupal网站。 它在服务器上的用户注册期间与POST请求完美协作。
那么朋友们,对此有何建议?为什么它不仅仅是发布文章?
您可以尝试检查:How to do http post using apache httpclient with web authentication?
它采用了HttpInterceptor
需要时
让我试试吧。然后我会在这里更新信息。谢谢。 – 2012-08-09 10:31:14
嗨,我已经尝试过与该链接中提到的HttpRequestInterceptor解决方案。但现在我得到这个错误“身份验证错误:预期的基本授权挑战,但没有找到”...任何解决方案呢? – 2012-08-09 11:34:01
为什么它从PhoneGap的,但不是Java的作品注入验证数据。 PhoneGap在Web容器中运行应用程序,因此已经通过身份验证 - 并且您拥有所有正确的Cookie。 AJAX将共享相同的会话,并且一切都“正常”。
但HTTPClient是一个完全不同的 - 你正在发起一个全新的HTTP会话,一切都必须是正确的。
上验证如何HTTP工作的几点意见:
有几种HTTP认证方法 - 这是该选择哪个Web服务器。在继续之前,请检查您的Drupal配置以确定它是否为:
- 基本身份验证(用户名和密码)。每个人和他们的狗支持这一点,但它是非常不安全的。请参阅http://en.wikipedia.org/wiki/Basic_access_authentication以获取更多详细信息
- Digest(用户名和挑战/响应hash与MD5)这更安全,但更复杂请注意,现在MD5通常被认为很弱,许多库支持它,包括Apache。
- 在IIS上实现的NTLM(Kerberos/SPEGNO的变体)。尽管HTTPClient确实声称使用不同的Credentials对象,但通常不支持Java。见http://hc.apache.org/httpclient-3.x/authentication.html#NTLM
(还要注意的是,Web容器具有“智慧”,能够尝试不同的认证方法由服务器的要求,所有在幕后)
同时检查Drupal的网络日志。几点:
- 您是否看到HTTPClient连接在所有。并且URL是正确的资源。从服务器的角度来看,总是值得检查 ...
- 它是否转到了正确的服务器?可能出现什么问题的一个例子:您是否在URL中使用IP 地址来对付多宿主Web服务器,因此请求会发送到错误的服务器?
- 检查通过先发制人的客户端发送的验证是正确的类型(基本,摘要,NTLM)
让我知道,如果这有助于。如果没有,并且你可以根据这篇文章提供更多的细节,我可以跟进更多的建议。
嗨安德鲁谢谢你的回复。请检查我编辑过的问题。我在Google上搜索过,发现了一些有趣的东西。是的,我检查了服务器日志,HttpClient与服务器连接。 – 2012-08-18 08:16:04
太好了。我阅读了这些回复。大部分问题和错误似乎都与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
这也是一篇有用的文章,虽然针对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头文件中添加令牌类型,并且更容易被制作)。
一旦一切按预期工作,在您的客户端重现相同的呼叫,标题和正文,您就可以开始了。
要特别注意JSON嵌套和数组。一些服务不支持(或期待)只是一种请求。 (即:使用对象而不是数组类型的属性名称 - >“provider [0]”:“DHL”等)。 – 2012-08-18 08:50:38
嗨,何塞,谢谢你的回复。 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");
}
});
}
我也看到了这个问题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
尝试http:// stackoverflow。com/questions/8022800/problems-doing-ajax-requests-with-a-phonegap-application – 2012-08-09 10:25:09
@ChanchalShelar我没有遇到PhoneGap的问题......它完美地工作......我有Android Java应用程序的问题。所以在这里我的问题是:相同的服务器与Phonegap协同工作,那么为什么它不适用于Android。 – 2012-08-09 10:28:44