2010-01-13 3 views
9

Je fais une authentification simple HTTP et je obtenir unJava: chercher URL avec HTTPBasic authentification

java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic OGU0ZTc5ODBk(...trimmed from 76 chars...) 
(...more password data...) 

que je pense est dû me avoir un nom d'utilisateur très long et mot de passe et l'encodeur enveloppe avec un \n à 76 caractères. Y a-t-il un moyen de contourner cela? L'URL ne prend en charge que l'authentification HTTP de base.

Voici mon code:

private class UserPassAuthenticator extends Authenticator { 
    String user; 
    String pass; 
    public UserPassAuthenticator(String user, String pass) { 
     this.user = user; 
     this.pass = pass; 
    } 

    // This method is called when a password-protected URL is accessed 
    protected PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(user, pass.toCharArray()); 
    } 
} 

private String fetch(StoreAccount account, String path) throws IOException { 
    Authenticator.setDefault(new UserPassAuthenticator(account.getCredentials().getLogin(), account.getCredentials().getPassword())); 

    URL url = new URL("https", account.getStoreUrl().replace("http://", ""), path); 
    System.out.println(url); 

    URLConnection urlConn = url.openConnection(); 
    Object o = urlConn.getContent(); 
    if (!(o instanceof String)) 
     throw new IOException("Wrong Content-Type on " + url.toString()); 

    // Remove the authenticator back to the default 
    Authenticator.setDefault(null); 
    return (String) o; 
} 
+0

Un avis de sécurité: si l'utilisation du nom d'utilisateur et mot de passe via HTTP, à la fois les choses sont envoyées en tant que chaîne claire. Il vaut mieux utiliser une authentification différente (formulaire, POST) et un protocole de transport (HTTPS, H2). – tfb785

Répondre

17

qui semble être un bug in Java.

Avez-vous essayé d'utiliser d'autres clients HTTP, tels que la bibliothèque d'Apache?

Ou au lieu d'utiliser l'Authenticator, de définir manuellement l'en-tête?

URL url = new URL("http://www.example.com/"); 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
connection.setRequestProperty("Authorization", "Basic OGU0ZTc5ODBkABcde...."); 

La valeur du jeton est encodeBase64 ("nom d'utilisateur: mot de passe").

+8

Fonctionne très bien tant que je fais le correctif de votre message de bug. \t \t 'String encoding = nouveau sun.misc.BASE64Encoder(). Encoder (userpass.getBytes()); \t \t // Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459815 \t \t encoding = encoding.replaceAll ("\ n", ""); '. Merci –

+1

Un mot de passe 64 caractères échoue toujours pour moi lors de l'authentification par rapport à une API REST Atlassian (comme Bamboo). Remplacer les nouvelles lignes ne suffisait pas dans mon cas. Groovy HTTPBuilder et AHC gèrent correctement le mot de passe long. –

+0

Merci, Oracle, pour avoir gaspillé 30 minutes de mon temps avec cette idiotie. (Réponse upvoted, sincères remerciements) – cbmanica

1

Cela fonctionne pour moi.

HttpsURLConnection con = null; con = (HttpsURLConnection) obj.openConnection(); Codage de chaîne = Base64.getEncoder(). EncodeToString ("nom d'utilisateur: mot de passe" .getBytes (StandardCharsets.UTF_8)); con.setRequestProperty ("Authorization", "Basic" + encoding.replaceAll ("\ n", ""));

0

J'ai trouvé que le caractère illégal a été causé par « Autorisation: Basic », codé qui devrait être « Autorisation », « Basic » + codé