title: Generating an SAS Token in Java to download a file in an Azure Data Storage container
body: <p>Trying to generate an SAS Token to access certain files in a Storage Account.  I'm using the methods listed here:</p>
  
  <p><a href="https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token</a></p>
  
  <p>Now, the problem I have is I cannot, for the life of me, make the sasToken string work.  If I generate the token via the Portal (Shared Access Signature in the Storage Account), I can access those files via a URL with the provided Token.</p>
  
  <p>However I have yet to be able to generate an SAS token programmatically via Java using the methods I linked above.  I think my problem is the StringToSign that is being encrypted.  I've been following this example when constructing the string to encrypt:</p>
  
  <p><a href="https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas</a></p>
  
  <p>All my efforts have resulted in either:</p>
  
  <pre><code>&lt;AuthenticationErrorDetail&gt;Signature fields not well formed.&lt;/AuthenticationErrorDetail&gt;
  </code></pre>
  
  <p>or</p>
  
  <pre><code>&lt;AuthenticationErrorDetail&gt;Signature did not match. String to sign used was &lt;insert string details here&gt;
  </code></pre>
  
  <p>Looking at the Portal generated sasToken that works for me:</p>
  
  <p>?sv=2017-11-09&amp;ss=f&amp;srt=o&amp;sp=r&amp;se=2018-12-06T22:15:20Z&amp;st=2018-12-06T14:15:20Z&amp;spr=https&amp;sig=%2Bi1TWv5D80U%2BoaIeoBh1wjaO1p4xVFx4nRZt%2FzwiszY%3D</p>
  
  <p>It seems I need a String like so:</p>
  
  <pre><code>            String stringToSign = accountName + "\n" +
                  "r\n" +
                  "f\n" +
                  "o\n" +
                  URLEncoder.encode(start, "UTF-8") + "\n" +
                  URLEncoder.encode(expiry, "UTF-8") + "\n" +
                  "\n" +
                  "https\n" +
                  azureApiVersion;
  </code></pre>
  
  <p>Where accountName is the storage account name from Azure, and start/expiry are the start and expiry strings (ie- 2018-12-06T22:15:20Z) and azureApiVersion is "2017-11-09".</p>
  
  <p>I then try to return the token after constructing the string like so:</p>
  
  <pre><code>        String signature = getHMAC256(key, stringToSign);
          sasToken = "sv=" + azureApiVersion +
                  "&amp;ss=f" +
                  "&amp;srt=o" +
                  "&amp;sp=r" +
                  "&amp;se=" +URLEncoder.encode(expiry, "UTF-8") +
                  "&amp;st=" + URLEncoder.encode(start, "UTF-8") +
                  "&amp;spr=https" +
                  "&amp;sig=" + URLEncoder.encode(signature, "UTF-8");
  </code></pre>
  
  <p>I've tried URL encoding and not URL encoding the the start/expiry dates as well, just in case that was messing things up.  What am I missing?</p>