Java: fetch URL with HTTPBasic Authentication

13,296

Solution 1

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").

Solution 2

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

Share:
13,296

Related videos on Youtube

Paul Tarjan
Author by

Paul Tarjan

I'm a Distinguished Engineer at Robinhood. I used to be the Tech Lead of Developer Productivity at Stripe where I built Sorbet. Before that I was the CTO and cofounder at Trimian. Before that I was a Software Engineer at Facebook on HHVM and the Open Graph. Before that I was the Tech Lead for Yahoo! SearchMonkey. See my homepage for more.

Updated on April 16, 2022

Comments

  • Paul Tarjan
    Paul Tarjan about 2 years

    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;
    }
    
  • Paul Tarjan
    Paul Tarjan over 14 years
    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", ""); . Thanks
  • Karl the Pagan
    Karl the Pagan over 11 years
    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.
  • cbmanica
    cbmanica almost 10 years
    Thanks, Oracle, for wasting 30 minutes of my time with this idiocy. (Answer upvoted, sincere thanks)