Java: fetch URL with HTTPBasic Authentication
Asked Answered
H

4

9

I'm doing some simple HTTP authentication and am getting a

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

which I think is due to me having a really long username and password and the encoder wraps it with a \n at 76 chars. Is there any way I can get around this? The URL only supports HTTP Basic Auth.

Here is my 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;
}
Hymnist answered 13/1, 2010 at 5:40 Comment(1)
A security notice: if use user name and password via HTTP, both things are send as clear string. Its better to use different authentication (form, POST) and transport protocol (HTTPS, H2).Appendant
A
17

That seems to be a bug in Java.

Have you tried using alternative HTTP clients, such as the library from Apache?

Or instead of using the Authenticator, manually setting the header?

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

The token value is encodeBase64("username:password").

Amaryl answered 13/1, 2010 at 6:2 Comment(3)
Works great as long as I do the fix from your bug post. String encoding = new sun.misc.BASE64Encoder().encode (userpass.getBytes()); // Java bug : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459815 encoding = encoding.replaceAll("\n", ""); . ThanksHymnist
A 64 character password still fails for me when authenticating against an Atlassian REST API (like Bamboo). Replacing newlines wasn't enough in my case. Groovy HTTPBuilder and AHC correctly handle the long password.Protrusive
Thanks, Oracle, for wasting 30 minutes of my time with this idiocy. (Answer upvoted, sincere thanks)Socialist
Z
1

This works for me .

HttpsURLConnection con = null; con = (HttpsURLConnection) obj.openConnection(); String encoding = Base64.getEncoder().encodeToString("username:password".getBytes(StandardCharsets.UTF_8)); con.setRequestProperty("Authorization","Basic "+encoding.replaceAll("\n", ""));

Zohara answered 9/1, 2017 at 9:33 Comment(0)
K
0

I found that the illegal character was caused by "Authorization: Basic ", encoded which should be "Authorization", "Basic " + encoded

Kathyrnkati answered 1/6, 2017 at 12:44 Comment(0)
G
0

changing from "Authorization: Basic ", encoded to "Authorization", "Basic " + encoded solved my illegal character in header issue.

Gabrielson answered 8/6, 2020 at 5:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.