Bug in HTTPBasicAuthFilter

com.sun.jersey.api.client.filter.HTTPBasicAuthFilter incorrectly pads the Base64 encoded strings with null characters, instead of ‘=’. jersey-client-1.0.3.jar

It might be better to use a pre-exisiting Base64 library. Like the one in CommonsCodec.

public class HttpBasicFilter extends ClientFilter
{
   private static final String c_base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                                              "abcdefghijklmnopqrstuvwxyz0123456789+/";
 
   private final String m_authentication;
 
   /**
    * Adds an authentication header using a username and password
    *
    * @param username the user name to send
    * @param password the passowrd to send
    */
   public HttpBasicFilter(final String username, final String password)
   {
      m_authentication = "Basic " + encode(username + ":" + password);
   }
 
   private String encode(final String string)
   {
      byte[] bytes = getBytes(string);
      final int padding = (3 - (bytes.length % 3)) % 3;
 
      bytes = zeroPad(bytes.length + padding, bytes);
 
      final StringBuilder encoded = new StringBuilder();
      for (int i = 0; i < bytes.length; i += 3)
      {
         final int threeBytes = (bytes[i] << 16) + (bytes[i + 1] << 8) + bytes[i + 2];
         encoded.append(c_base64code.charAt((threeBytes >> 18) & 0x3f)).
                 append(c_base64code.charAt((threeBytes >> 12) & 0x3f)).
                 append(c_base64code.charAt((threeBytes >> 6) & 0x3f)).
                 append(c_base64code.charAt(threeBytes & 0x3f));
      }
      return encoded.substring(0, encoded.length() - padding) + "==".substring(0, padding);
   }
 
   private byte[] getBytes(final String string)
   {
      byte[] bytes;
      try
      {
         bytes = string.getBytes("UTF-8");
      }
      catch (final UnsupportedEncodingException e)
      {
         g_logger.log(Level.WARNING, "unable to decode string as UTF-8", e);
         bytes = string.getBytes();
      }
      return bytes;
   }
 
   private byte[] zeroPad(final int length, final byte[] bytes)
   {
      final byte[] padded = new byte[length];
      System.arraycopy(bytes, 0, padded, 0, bytes.length);
      return padded;
   }
 
   /**
    * {@inheritDoc}
    */
   @Override
   public ClientResponse handle(final ClientRequest request) throws ClientHandlerException
   {
      if (!request.getMetadata().containsKey(HttpHeaders.AUTHORIZATION))
      {
         request.getMetadata().add(HttpHeaders.AUTHORIZATION, m_authentication);
      }
      return getNext().handle(request);
   }
}

Leave a Reply

Your email address will not be published. Required fields are marked *