2011-08-15 3 views
4

j'effectuer une requête GET:Android, HttpURLConnection et manipulation de mauvaises références

HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); 
urlConnection.setConnectTimeout(CONNECT_TIMEOUT); 
urlConnection.setReadTimeout(READ_TIMEOUT); 
urlConnection.connect(); 

par laquelle les pouvoirs ont déjà été établis avec:

Authenticator.setDefault(new Authenticator() { 
    protected PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(loginNameString, passwordString.toCharArray()); 
    } 
}); 

Tout fonctionne bien quand je l'offre bon informations d'identification (c'est-à-dire nom d'utilisateur et mot de passe).

Qu'advient-il de la connexion lorsque de mauvaises informations d'identification sont fournies? Par exemple, si je fournis délibérément des informations d'identification incorrectes et que j'appelle le urlConnection.getResponseCode() immédiatement après urlConnection.connect(), mon application finit par expirer et je dois forcer de près. Pourquoi donc?

** Modifier. Pour autant que je sache, le HttpURLConnection continue d'essayer de se connecter (même avec un timeout fini) quand les informations d'identification sont mauvaises. (Je le sais parce que j'ai ajouté la ligne Log.v("Authentication", "Calling..."); dans ma méthode getPasswordAuthentication() avant de revenir). Je veux que la connexion arrête d'essayer si elle échoue pour de mauvaises références!

Répondre

7

Avec auth de base, la solution de contournement est:

connection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.DEFAULT)); 

Utiliser package android.util.Base64. Notez également que la méthode encodeToString() est disponible depuis API 8 (Android 2.2). En outre, http://code.google.com/p/android/issues/detail?id=7058 est pertinent.

+0

merci! ce bogue 7058 dans aosp est exactement celui-ci - nous sommes censés demander à l'utilisateur un nouvel ensemble d'informations d'identification car celles-ci ont échoué. – Maks

0

J'ai découvert que la mise en Authorization résultats d'en-tête dans un code 400 de réponse sur 2.3.7 alors voici un Authenticator pincé à la place:

public class FixedAuthenticator extends Authenticator { 

    private PasswordAuthentication passAuth; 

    public FixedAuthenticator(PasswordAuthentication passAuth) { 
     this.passAuth = passAuth; 
    } 

    @Override 
    protected PasswordAuthentication getPasswordAuthentication() { 
     try { 
      return passAuth; 
     } finally { 
      passAuth = null; 
     } 
    } 
} 

Vous aurez besoin de définir une nouvelle instance de celui-ci avant de se connecter :

... 
Authenticator.setDefault(new FixedAuthenticator(passAuth)); 
connection.connect(); 

A working example.

1

Vous pouvez résoudre ce problème en utilisant un indicateur et en retournant un null dans votre authentificateur après votre première fausse authentification.

De cette façon, votre InputStream lèvera une exception que vous pourrez gérer par la suite.

Copie de: https://stackoverflow.com/a/13615011/628713:

public class MyRequest 
{ 
    private boolean alreadyTriedAuthenticating = false; 
    private URL url; 

    ... 

    public void send() 
    { 
     HttpUrlConnection connection = (HttpUrlConnection) url.openConnection(); 
     Authenticator.setDefault(new Authenticator() { 
      protected PasswordAuthentication getPasswordAuthentication() { 
       if (!alreadyTriedAuthenticating) 
       { 
        alreadyTriedAuthenticating = true; 
        return new PasswordAuthentication(username, password.toCharArray()); 
       } 
       else 
       { 
        return null; 
       } 
      } 
      InputStream in = new BufferedInputStream(connection.getInputStream()); 

      ... 

    } 
} 
Questions connexes