Ошибка аутентификации: невозможно ответить на любую из этих проблем: {} Android - 401 Unauthorized

Ошибка аутентификации: невозможно ответить на любую из этих проблем: {} Android - 401 Несанкционированный

Я ссылался на эту ссылку Ошибка аутентификации при использовании HttpPost с DefaultHttpClient на Android

Я работаю над приложением Android в том, что поддерживается в Drupal. В этом я отправляю данные из приложения android на веб-сайт drupal - webservice в формате JSON. Теперь я могу читать данные JSON из веб-сервиса Drupal и записывать его в приложение для Android. Но столкнувшись с проблемой написания на drupal из android, он генерирует ответ со статусом

401 Несанкционированный

Из собственного приложения Android он генерирует 401, а из phonegap-from android, когда я запускаю запрос AJAX, он отлично работает и пишет статью или страницу на веб-сайте drupal. так что webservice отлично работает и

Android-приложение Android Android отлично работает, есть проблема с приложением JAVA для Android Я запускаю приложение для Android на 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, который я использую в своем коде. Проверьте эту ссылку. В этом сообщении Link от Джесси Уилсон из команды Dalvik. В этом случае они предлагают использовать HttpURLConnection вместо DefaultHttpClient, а также писать, что команда Android больше не будет разрабатывать Apache httpclient. поэтому его более старая версия, которую я использую.

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

2 вещь, которую я нашел в этой ссылке. Это говорит о том, что 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 на Android

Какая версия HTTP-клиента Apache поставляется в Android 1.6?

Из этих ссылок я сделал вывод, что если мы обновим Apache HttpClient до последней стабильной версии, тогда эта проблема может быть решена.

Но это прямо невозможно, так как Android Team официально остановила поддержку Apache httpclient.

С помощью этой ссылки можно было бы решить. Я не пробовал, но я работаю над этим.

Это библиотека, которая может помочь в обновлении версии httpclient в Android.

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

Другим решением может быть использование HttpURLConnection. Я также работаю над ним.

Но большинство людей здесь, в stackoverflow и в Интернете, похоже, используют Android с DefaultHttpCLient. И, конечно же, он также работает со мной на протяжении всего моего приложения, включая логин, регистрацию, чтение с сервера и сеанса и другие функции. Просто он не работает с прямой публикацией какой-либо статьи на моем сервере Drupal. Он отлично работает с запросом POST при регистрации пользователя на сервере.

Итак, друзья, любые предложения по этому поводу? почему он не работает только с публикацией статьи?

Ответ 1

Как это работает из PhoneGap, но не для Java. PhoneGap запускает приложение в веб-контейнере и поэтому уже аутентифицировано - и у вас есть все правильные файлы cookie. AJAX будет использовать один и тот же сеанс, и все "просто работает".

Однако HTTPClient совершенно другой - вы инициируете совершенно новый сеанс HTTP, и все должно быть правильно.

Несколько комментариев о том, как работает HTTP Auth:

Существует несколько методов проверки подлинности HTTP - и это выбирает веб-сервер. Прежде чем идти дальше, проверьте конфигурацию Drupal, чтобы выяснить, есть ли это:

  • Базовый Auth (имя пользователя и пароль). Все и их собаки поддерживают это, но это очень неуверенно. Подробнее см. http://en.wikipedia.org/wiki/Basic_access_authentication
  • Дайджест (имя пользователя и хеш-запрос/ответ с MD5.Это более безопасно, но гораздо сложнее.Просмотрите, что MD5 обычно считается слабым сейчас.Многие библиотеки поддерживают его, в том числе Apache. См. http://en.wikipedia.org/wiki/Digest_access_authentication для более подробной информации
  • NTLM (вариант Kerberos/SPEGNO), который реализован в IIS. Обычно это не поддерживается Java, хотя HTTPClient действительно исповедует - но использует другой объект Credentials. См. http://hc.apache.org/httpclient-3.x/authentication.html#NTLM

(Обратите внимание также, что веб-контейнер имеет "умники", чтобы иметь возможность попробовать разные методы аутентификации по запросу сервера, все за кулисами)

Также проверьте веб-журналы Drupal. Несколько указателей:

  • Вы видели, как HTTPClient подключается вообще. И URL-адрес идет к правильному ресурсу. Всегда стоит проверять с точки зрения сервера...
  • Пошел ли он на правильный сервер? Один пример того, что может пойти не так: используете ли вы IP-адрес адресов в URL-адресе против многоуровневого веб-сервера, поэтому запрос отправляется на неправильный сервер?
  • Убедитесь, что аутентификация, посланная клиентом упреждающим образом, является правильным типом (основной, дайджест, NTLM)

Сообщите мне, если это поможет. Если нет, и вы можете дать более подробную информацию в соответствии с этим сообщением, я могу продолжить консультации.

Ответ 3

Я бы предложил сначала протестировать PHP-версию приложения. Существует несколько способов сделать ваши собственные вызовы, включая заголовки и auth. От curl до GraphicalHttpClient (http://itunes.apple.com/us/app/graphicalhttpclient/id433095876?mt=12, я лично использую это и работает прилично). Там есть другие варианты, такие как отладчик клиента REST (https://addons.mozilla.org/en-US/firefox/addon/restclient/)

Таким образом, вы сможете протестировать свой вызов так многими способами, что боль делает непосредственно на клиенте (иногда это просто меняется с http на https или добавляет тип вашего токена в заголовок авторизации и это намного проще быть в состоянии летать).

Как только все будет работать так, как ожидается, воспроизведите тот же самый вызов, заголовки и тело в вашем клиенте, и вы готовы к работе.

Ответ 4

Я столкнулся с тем же "DefaultRequestDirector: Ошибка аутентификации: не удалось ответить на любую из этих проблем: {}" проблема с услугами Drupal с помощью loopj android -async-http library (настоятельно рекомендую).

Ключ к решению для меня был в комментарии Jose L Ugia в одном из ответов относительно уделения особого внимания выходу JSON от Drupal. Я пытался поймать JSONObject, но реальное сообщение было в формате массива "[" Неверное имя пользователя или пароль ".]". Переключение на JSONArray правильно зафиксировало ошибку и позволило мне обработать ее. В вашем случае я считаю, что это связано с тем, что вы не публикуете учетные данные для входа в систему, поскольку службы drupal ожидают его.

Вы должны помнить, что с помощью Drupal Services вы должны выполнять систему/подключение и захватывать сеанс, за которым следует пользователь/логин (и пароль/пароль, передаваемый как параметры) и захватывать сеанс, а затем все ваши последующие запросы должны работать. Вот почему мне нравится использовать библиотеку loopj, потому что делает все эти запросы более управляемыми. Вот очень простой пример подключения к drupal с loopj. Все последующие сообщения легко выполняются с использованием параметров.

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");
      }
    });
  }