/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.server.api.client; import java.io.UnsupportedEncodingException; import javax.ws.rs.core.HttpHeaders; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientRequest; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.filter.ClientFilter; /** * com.sun.jersey.api.client.filter.HTTPBasicAuthFilter incorrectly pads the Base64 encoded * strings with null characters, instead of . jersey-client-1.0.3.jar * * @author Decebal Suiu */ public class HttpBasicAuthenticationFilter extends ClientFilter { // TODO change with slf4j (in nextreports we use commons-logging) private static final Log LOG = LogFactory.getLog(HttpBasicAuthenticationFilter.class); private static final String BASE64CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; private String authentication; /** * Adds an authentication header using a username and password. * * @param username * the user name to send * @param password * the passowrd to send */ public HttpBasicAuthenticationFilter(String username, String password) { authentication = "Basic " + encode(username + ":" + password); } public ClientResponse handle(ClientRequest request) throws ClientHandlerException { if (!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) { request.getHeaders().add(HttpHeaders.AUTHORIZATION, authentication); } return getNext().handle(request); } private String encode(String text) { byte[] bytes = getBytes(text); int padding = (3 - (bytes.length % 3)) % 3; bytes = zeroPad(bytes.length + padding, bytes); StringBuilder encoded = new StringBuilder(); for (int i = 0; i < bytes.length; i += 3) { int threeBytes = (bytes[i] << 16) + (bytes[i + 1] << 8) + bytes[i + 2]; encoded.append(BASE64CODE.charAt((threeBytes >> 18) & 0x3f)) .append(BASE64CODE.charAt((threeBytes >> 12) & 0x3f)) .append(BASE64CODE.charAt((threeBytes >> 6) & 0x3f)) .append(BASE64CODE.charAt(threeBytes & 0x3f)); } return encoded.substring(0, encoded.length() - padding) + "==".substring(0, padding); } private byte[] getBytes(String text) { byte[] bytes; try { bytes = text.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { LOG.warn("Unable to decode string as UTF-8", e); bytes = text.getBytes(); } return bytes; } private byte[] zeroPad(int length, byte[] bytes) { byte[] padded = new byte[length]; System.arraycopy(bytes, 0, padded, 0, bytes.length); return padded; } }