Log in or register to post comments

401 Unauthorized - Adding a Target to a Cloud Database

August 5, 2014 - 1:02pm #1
Hi,
 
I'm using the VWC API with Java, but I have a problem:
 
When call a GET to get list of all targets in Database works perfect, but when I try to use a POST service always have like an answer "401 Unauthorized".
 
I use the same code of the sample (vuforia-web-services-sample-code-java-2-0-0)
 
Any ideas?
 
Thank you in advance,
Jose

401 Unauthorized - Adding a Target to a Cloud Database

August 7, 2014 - 12:29pm #2

I fixed the problem. Sample code does not work properly in Java 7...

I had to replace SignatureBuilder with this code:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SignatureBuilder {

	private static final Logger logger = LoggerFactory
			.getLogger(SignatureBuilder.class);

	public String tmsSignature(HttpUriRequest request, String secretKey) {
		String method = request.getMethod();
		String contentType = "";
		String hexDigest = "d41d8cd98f00b204e9800998ecf8427e"; // Hex digest of
																// an empty
																// string

		if (method.equalsIgnoreCase("GET") || method.equalsIgnoreCase("DELETE")) {
			// Do nothing because the strings are already set correctly
		} else if (method.equalsIgnoreCase("POST")
				|| method.equalsIgnoreCase("PUT")) {
			contentType = "application/json";
			// If this is a POST or PUT the request should have a request body
			try {
				hexDigest = md5((HttpEntityEnclosingRequestBase) request);
			} catch (NoSuchAlgorithmException e) {
				logger.error("ERROR: No such algorithm:" + e.getMessage());
			} catch (UnsupportedEncodingException e) {
				logger.error("ERROR: Unsupported encoding:" + e.getMessage());
			}
		} else {
			logger.error("ERROR: Invalid content type passed to Sig Builder");
		}

		// Date in the header and date used to calculate the hash must be the
		// same
		String dateValue = request.getFirstHeader("Date").getValue();
		String requestPath = request.getURI().getPath();
		String toDigest = new String(method + "\n" + hexDigest + "\n"
				+ contentType + "\n" + dateValue + "\n" + requestPath);
		String shaHashed = "";
		try {
			logger.info("toDigest" + toDigest);
			shaHashed = calculateRFC2104HMAC(secretKey, toDigest);
		} catch (SignatureException e) {
			logger.error("Error making digest:" + e.getMessage());
		}
		return new String(shaHashed);
	}

	public static String md5(HttpEntityEnclosingRequestBase httpMethod)
			throws NoSuchAlgorithmException, UnsupportedEncodingException {
		ByteArrayOutputStream requestOutputStream = new ByteArrayOutputStream();
		try {
			httpMethod.getEntity().writeTo(requestOutputStream);
		} catch (IOException e) {
			logger.error("ERROR: IOException caught when writing Content MD5 hash:"
					+ e.getMessage());
		}

		MessageDigest md;
		md = MessageDigest.getInstance("MD5");
		byte[] md5hash = new byte[32];
		md.update(requestOutputStream.toByteArray());
		md5hash = md.digest();
		return convertToHex(md5hash);
	}

	private static String convertToHex(byte[] data) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < data.length; i++) {
			int halfbyte = (data[i] >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				if ((0 <= halfbyte) && (halfbyte <= 9))
					buf.append((char) ('0' + halfbyte));
				else
					buf.append((char) ('a' + (halfbyte - 10)));
				halfbyte = data[i] & 0x0F;
			} while (two_halfs++ < 1);
		}

		logger.info("Hex:" + buf.toString());
		return buf.toString();
	}

	public static String calculateRFC2104HMAC(String key, String data)
			throws java.security.SignatureException {
		String result = "";
		try {
			// get an hmac_sha1 key from the raw key bytes
			SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(),
					"HmacSHA1");
			// get an hmac_sha1 Mac instance and initialize with the signing key
			Mac mac = Mac.getInstance("HmacSHA1");
			mac.init(signingKey);
			// compute the hmac on input data bytes
			byte[] rawHmac = mac.doFinal(data.getBytes());
			// base64-encode the hmac
			result = Base64.encodeBase64String(rawHmac);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

 

Log in or register to post comments