Java:使用HTTPBasic身份验证获取URL

9
我正在进行简单的HTTP身份验证,但出现了一个问题。
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic OGU0ZTc5ODBk(...trimmed from 76 chars...)
(...more password data...)

我认为这是因为我的用户名和密码太长了,编码器在76个字符处用\n换行。有没有办法解决这个问题?URL仅支持HTTP基本身份验证。

这是我的代码:

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

一条安全提示:如果通过HTTP使用用户名和密码,这两个信息都会以明文形式发送。最好使用不同的身份验证方式(表单、POST)和传输协议(HTTPS、H2)。 - Mirko Ebert
4个回答

17
似乎这是Java中的一个问题。
你尝试过使用其他的HTTP客户端吗,比如Apache的库?
或者不使用Authenticator,手动设置头部呢?
URL url = new URL("http://www.example.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Authorization", "Basic OGU0ZTc5ODBkABcde....");

令牌值是encodeBase64("用户名:密码")。

8
只要我按照你的错误帖子中的修复方式操作,它就能正常工作。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", ""); 谢谢。 - Paul Tarjan
1
当我对Atlassian REST API(如Bamboo)进行身份验证时,即使使用64个字符的密码仍然失败。在我的情况下,替换换行符是不够的。Groovy HTTPBuilder和AHC可以正确处理长密码。 - Karl the Pagan
感谢Oracle浪费了我30分钟的时间,让我遇到这种愚蠢的问题。(答案得到赞同,真诚感谢) - cbmanica

1

这对我有效。

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


0

我发现非法字符是由"Authorization: Basic "编码引起的,应该是"Authorization","Basic "+编码


0

将编码后的"Authorization: Basic "更改为"Authorization",并在后面添加"Basic ",解决了我的头部非法字符问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接