2

I have a Jersey client running on Wildfly 9 with BASIC authentication enabled. This works well in general, but when using passwords with special characters (such as German umlauts) I get this exception, related to Base64 encoding:

Caused by: java.lang.ArrayIndexOutOfBoundsException: 255
        at org.glassfish.jersey.internal.util.Base64.encode(Base64.java:112)
        at org.glassfish.jersey.internal.util.Base64.encodeAsString(Base64.java:160)
        at org.glassfish.jersey.client.filter.HttpBasicAuthFilter.<init>(HttpBasicAuthFilter.java:98)
        at org.glassfish.jersey.client.filter.HttpBasicAuthFilter.<init>(HttpBasicAuthFilter.java:72)

Any idea what I might be doing wrong?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
j-dimension
  • 119
  • 10
  • @Tom Frankly, you're severely confusing "character encoding" with "Base64 encoding". – BalusC Sep 26 '17 at 22:19
  • Tom, I am aware of character set handling and byte - String - byte conversions. However, I do not see in which place I might be doing something wrong here. – j-dimension Sep 27 '17 at 06:00
  • I've had some people who know these protocols very well tell me that what should be stated is that BASIC requires usernames & passwords to be chars 32 ... 127. It's not part of the official spec, but in practice it often is an implementation limitation. – David Thielen Apr 26 '18 at 17:38

1 Answers1

1

This is a known bug.

As a workaround you can set the Authorization header directly instead of using the HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_USERNAME and HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_PASSWORD properties.

Old code:

Invocation.Builder builder = …;
builder
    .property(HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_USERNAME, username)
    .property(HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_PASSWORD, password);

New code:

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.ws.rs.core.HttpHeaders;

// …
    builder.header(HttpHeaders.AUTHORIZATION, calculateAuthentication(username, password));
// …

private String calculateAuthentication(final String username, final byte[] password) {
    final byte[] prefix = (username + ":").getBytes(StandardCharsets.UTF_8);
    final byte[] usernamePassword = new byte[prefix.length + password.length];
    System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length);
    System.arraycopy(password, 0, usernamePassword, prefix.length, password.length);
    return "Basic " + Base64.getEncoder().encodeToString(usernamePassword);
}
Martin
  • 2,573
  • 28
  • 22