12 votes

Erreur d'authentification : Impossible de répondre à l'un de ces défis : {} Android - 401 Unauthorized

Erreur d'authentification : Impossible de répondre à l'un de ces défis : {} Android - 401 Unauthorized

J'ai pris la référence de ce lien Erreur d'authentification lors de l'utilisation de HttpPost avec DefaultHttpClient sur Android

Je travaille sur une application Android qui est soutenue par Drupal. Dans ce cas, j'envoie des données de l'application Android au site Web de Drupal - webservice au format JSON. Maintenant, je peux lire les données JSON du webservice Drupal et les écrire dans mon application Android. Mais je suis confronté à un problème d'écriture sur Drupal à partir d'Android, qui génère une réponse avec un code d'état.

401 Non autorisé

Depuis l'application native Android, il génère 401 , tandis que depuis phonegap- Android, lorsque je lance une requête AJAX, cela fonctionne parfaitement et écrit un article ou une page sur le site Web Drupal. Cela signifie donc que le service Web fonctionne parfaitement.

mon application Android phonegap fonctionne parfaitement, mais il y a un problème avec l'application Android native JAVA. J'exécute mon application Android sur Android2.3.4 -> Samsung Galaxy S Plus - Samsung GT-I9001

Voici mon code pour 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;
            }

    }

   }

Voici le logcat que je reçois.

 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

Voici ma requête PhoneGap Ajax, elle fonctionne parfaitement.

$('#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;

});

\=================================================================================

Edit :

J'ai essayé différentes méthodes pour Apache httpclient pour mon erreur.pendant ce temps, j'ai fait quelques recherches et cherché sur google et trouvé des choses intéressantes.

1er J'ai découvert qu'Android-Google ne recommande pas officiellement Apache HttpClient que j'utilise dans mon code. Vérifiez ce lien. Dans ce lien, un message de Jesse Wilson de l'équipe Dalvik. Ils suggèrent d'utiliser HttpURLConnection au lieu de DefaultHttpClient et écrivent également que l'équipe Android ne développera plus Apache httpclient. C'est donc l'ancienne version que j'utilise.

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

2ème que j'ai trouvé sur ce lien. Il suggère que Android est livré avec la version 4.0 Beta2 du HttpClient d'Apache, qui présente un écueil en ce qui concerne l'authentification de base. La méthode d'authentification que j'utilise est celle de HttpClient 3.x , que j'ai trouvée sur ce lien. Vérifiez le lien. http://hc.apache.org/httpclient-3.x/authentication.html#Preemptive_Authentication

Donc le problème de la version.

http://dlinsin.blogspot.in/2009/08/http-basic-authentication-with-Android.html

J'ai également trouvé quelques liens avec des solutions potentielles à ce problème.

http://ogrelab.ikratko.com/using-newer-version-of-httpclient-like-4-1-x/

Apache HttpClient 4.1 sur Android

Quelle version du client HTTP Apache est incluse dans Android 1.6 ?

A partir de ces liens, j'ai conclu que si nous mettons à jour Apache HttpClient à la dernière version stable, alors ce problème peut être résolu.

Mais ce n'est plus possible, car l'équipe Android a officiellement cessé de prendre en charge le client http d'Apache.

Avec ce lien, il pourrait être possible de résoudre. Je ne l'ai pas encore essayé mais j'y travaille.

C'est la bibliothèque qui peut aider à mettre à jour la version de httpclient dans Android.

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

L'autre solution pourrait être d'utiliser HttpURLConnection J'y travaille également.

Mais la plupart des gens ici sur stackoverflow et sur Internet semblent utiliser DefaultHttpCLient avec Android. Et bien sûr, il fonctionne également avec moi dans toute mon application, y compris la connexion, l'enregistrement, la lecture du serveur et de la session et d'autres fonctionnalités, mais il ne fonctionne pas avec la publication directe d'un article sur mon site Web Drupal. Il fonctionne parfaitement avec la demande POST pendant l'enregistrement de l'utilisateur sur le serveur.

Alors mes amis, avez-vous des suggestions à ce sujet ? Pourquoi cela ne fonctionne-t-il pas simplement en postant un article ?

2voto

Andrew Alcock Points 10536

Comment se fait-il que cela fonctionne à partir de PhoneGap mais pas de Java. PhoneGap exécute l'application dans un conteneur web et a donc déjà été authentifié - et vous avez tous les bons cookies. AJAX partage la même session et tout fonctionne.

Cependant, le cas de HTTPClient est complètement différent : vous lancez une toute nouvelle session HTTP et tout doit être parfait.

Quelques commentaires sur le fonctionnement de HTTP Auth :

Il existe plusieurs méthodes d'authentification HTTP - et c'est le serveur web qui choisit laquelle. Avant d'aller plus loin, vérifiez votre configuration Drupal pour savoir si c'est le cas :

(Notez également que le conteneur web est suffisamment intelligent pour pouvoir essayer différentes méthodes d'authentification à la demande du serveur, tout cela en coulisse).

Vérifiez également les journaux Web de Drupal. Quelques conseils :

  • Avez-vous vu le HTTPClient se connecter du tout . Et l'URL renvoie-t-il à la bonne ressource ? Cela vaut toujours la peine de vérifier du point de vue du serveur ...
  • Est-ce que ça a été envoyé au bon serveur ? Voici un exemple de ce qui peut mal se passer : Utilisez-vous des adresses IP dans l'URL d'un serveur web à hébergement multiple, de sorte que la demande est envoyée au mauvais serveur ?
  • Vérifier que l'authentification envoyée par le client de manière préemptive est du bon type (basic, digest, NTLM)

Faites-moi savoir si cela vous aide. Si ce n'est pas le cas, et si vous pouvez donner plus de détails comme dans cet article, je peux suivre avec plus de conseils.

1voto

SztupY Points 4586

Vous pourriez essayer de vérifier : Comment faire un post http en utilisant apache httpclient avec une authentification web ?

Il utilise un HttpInterceptor pour injecter les données d'authentification, le cas échéant

1voto

Jose L Ugia Points 1787

Je vous suggère de tester d'abord la partie PHP de l'application. Il y a plusieurs façons de faire vos propres appels, y compris les en-têtes et l'authentification. De curl à GraphicalHttpClient (http://itunes.apple.com/us/app/graphicalhttpclient/id433095876?mt=12 , je l'utilise personnellement et il fonctionne correctement). Il existe d'autres options comme REST client debugger (https://addons.mozilla.org/en-US/firefox/addon/restclient/).

De cette façon, vous pourrez tester votre appel de nombreuses façons, ce qui est difficile à faire directement dans le client (parfois, il suffit de passer de http à https ou d'ajouter le type de votre jeton dans l'en-tête d'autorisation, ce qui est beaucoup plus facile à faire à la volée).

Une fois que tout fonctionne comme prévu, reproduisez le même appel, les mêmes en-têtes et le même corps dans votre client et vous êtes prêt à partir.

1voto

7wonders Points 1427

Je rencontrais le même problème "DefaultRequestDirector : Erreur d'authentification : Impossible de répondre à l'un de ces défis : {}" avec les services Drupal utilisant l'option bibliothèque loopj Android-async-http (fortement recommandé).

La clé de la solution pour moi se trouvait dans le commentaire de Jose L Ugia dans l'une des réponses concernant l'attention particulière à accorder à la sortie JSON de Drupal. J'essayais d'attraper un JSONObject mais le vrai message était au format array "["Wrong username or password."]". Le passage à JSONArray a permis de détecter l'erreur correctement et de la traiter. Dans votre cas, je pense que c'est parce que vous n'affichez pas les informations de connexion comme les services Drupal l'attendent.

Rappelez-vous qu'avec les services Drupal, vous devez faire system/connect et récupérer la session, puis user/login (avec l'utilisateur et le mot de passe passés en paramètres) et récupérer la session, et toutes vos requêtes suivantes devraient fonctionner. C'est pourquoi j'aime utiliser la bibliothèque loopj, car elle rend toutes ces requêtes plus faciles à gérer. Voici un exemple très basique de connexion à Drupal avec loopj. Tous les posts suivants sont facilement réalisés en utilisant les paramètres.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X