Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>EDIT</strong> Where did Gaurav's answer go? :-) I believe he already answered and mentioned that you appear to be constructing a Shared Key Lite signature and should thus use "SharedKeyLite" in your authorization header.</p> <hr> <p>I think Gaurav is right in his answer, but I noticed three other issues:</p> <ol> <li>You seem to be making a call to <code>http://localhost/devstoreaccount1</code>, but you're computing a signature for <code>http://localhost/devstoreaccount1/tweet/?comp=list</code>. Make sure the URLs match up.</li> <li>For the storage emulator, I think your canonicalized resource should actually be <code>/devstoreaccount1/devstoreaccount1/tweet/?comp=list</code>. (Note the repetition of the account name.) It should generally be <code>/&lt;account&gt;/&lt;path&gt;</code>, and for the storage emulator, the account name shows up in the path.</li> <li>Where's the <code>x-ms-version</code> header? I <em>believe</em> that's required.</li> </ol> <p><strong>UPDATE</strong> Here's some working code with two methods, one that uses Shared Key and one that uses Shared Key Lite. Hopefully this clears things up. Note that to use the storage emulator, you'll want to switch the URL back to <code>localhost:10000/devstoreaccount1</code>. The signature code should still work for the emulator, but I haven't tested it. The Base64 library came from here: <a href="http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html" rel="noreferrer">http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html</a>.</p> <pre><code>import java.net.*; import java.util.*; import java.text.*; import javax.crypto.*; import javax.crypto.spec.*; import org.apache.commons.codec.binary.Base64; public class Test { private static Base64 base64 = new Base64(); public static void signRequestSK(HttpURLConnection request, String account, String key) throws Exception { SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); fmt.setTimeZone(TimeZone.getTimeZone("GMT")); String date = fmt.format(Calendar.getInstance().getTime()) + " GMT"; StringBuilder sb = new StringBuilder(); sb.append("GET\n"); // method sb.append('\n'); // content encoding sb.append('\n'); // content language sb.append('\n'); // content length sb.append('\n'); // md5 (optional) sb.append('\n'); // content type sb.append('\n'); // legacy date sb.append('\n'); // if-modified-since sb.append('\n'); // if-match sb.append('\n'); // if-none-match sb.append('\n'); // if-unmodified-since sb.append('\n'); // range sb.append("x-ms-date:" + date + '\n'); // headers sb.append("x-ms-version:2009-09-19\n"); sb.append("/" + account + request.getURL().getPath() + "\ncomp:list"); //System.out.println(sb.toString()); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(base64.decode(key), "HmacSHA256")); String authKey = new String(base64.encode(mac.doFinal(sb.toString().getBytes("UTF-8")))); String auth = "SharedKey " + account + ":" + authKey; request.setRequestProperty("x-ms-date", date); request.setRequestProperty("x-ms-version", "2009-09-19"); request.setRequestProperty("Authorization", auth); request.setRequestMethod("GET"); System.out.println(auth); } public static void signRequestSKL(HttpURLConnection request, String account, String key) throws Exception { SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); fmt.setTimeZone(TimeZone.getTimeZone("GMT")); String date = fmt.format(Calendar.getInstance().getTime()) + " GMT"; StringBuilder sb = new StringBuilder(); sb.append("GET\n"); // method sb.append('\n'); // md5 (optional) sb.append('\n'); // content type sb.append('\n'); // legacy date sb.append("x-ms-date:" + date + '\n'); // headers sb.append("x-ms-version:2009-09-19\n"); sb.append("/" + account + request.getURL().getPath() + "?comp=list"); //System.out.println(sb.toString()); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(base64.decode(key), "HmacSHA256")); String authKey = new String(base64.encode(mac.doFinal(sb.toString().getBytes("UTF-8")))); String auth = "SharedKeyLite " + account + ":" + authKey; request.setRequestProperty("x-ms-date", date); request.setRequestProperty("x-ms-version", "2009-09-19"); request.setRequestProperty("Authorization", auth); request.setRequestMethod("GET"); System.out.println(auth); } public static void main(String args[]) throws Exception { String account = args[0]; String key = args[1]; HttpURLConnection connection = (HttpURLConnection) (new URL("http://" + account + ".blob.core.windows.net/?comp=list")).openConnection(); signRequestSKL(connection, account, key); connection.connect(); System.out.println(connection.getResponseMessage()); connection = (HttpURLConnection) (new URL("http://" + account + ".blob.core.windows.net/?comp=list")).openConnection(); signRequestSK(connection, account, key); connection.connect(); System.out.println(connection.getResponseMessage()); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload