locked
Storage Blob Access Authentication Failed for ListBlobs, Put and others RRS feed

  • Question

  • This is the list blob rest api I am trying to hit. Earlier I posted a question about PUT BLOB REST API which was also giving me 403 forbidden error.

    Similarly for this I am getting:

    <Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

    Here is my code:

    package main;
    
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.TimeZone;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
    import com.sun.org.apache.xml.internal.security.utils.Base64;
    
    
    public class ListBlobs {
    
    	
    private String key="password";
    private String account="klabs";
    private String requestMethod = "GET";  
    private String urlPath = "/delete?restype=container&comp=list ";
    
    private String uRL="https://"+account+".blob.core.windows.net"+urlPath;
    
    private String date=createDate();
    private String storageServiceVersion = "2009-09-19";
    private String canonicalizedHeader="x-ms-date:"+date+"\nx-ms-version:"+storageServiceVersion+"\n";
    private String canonicalizedResource="/klabs/delete\ncomp:list\nrestype:container";
    private String stringToSign="GET\n\n\n\n\n\n\n\n\n\n\n\n"+canonicalizedHeader+canonicalizedResource;
    
    
    
    
    public static void main(String[] args) {
    
    ListBlobs blobs= new ListBlobs();
    try {
    	blobs.execute();
    } catch (InvalidKeyException e) {
    	e.printStackTrace();
    } catch (MalformedURLException e) {
    	e.printStackTrace();
    } catch (Base64DecodingException e) {
    	e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
    	e.printStackTrace();
    } catch (IllegalStateException e) {
    	e.printStackTrace();
    } catch (IOException e) {
    	e.printStackTrace();
    }
    
    }
    
    public void execute() throws MalformedURLException, IOException, InvalidKeyException, Base64DecodingException, NoSuchAlgorithmException, IllegalStateException {
    
    System.out.println(stringToSign);
    String Authorization=createAuthorizationHeader(stringToSign);
    System.out.println(Authorization);
    HttpURLConnection connection= (HttpURLConnection) new URL(uRL).openConnection();
    connection.setRequestMethod("GET");
    
    connection.setRequestProperty("x-ms-date", date);
    connection.setRequestProperty("x-ms-version", storageServiceVersion);
    connection.setRequestProperty("Authorization", Authorization);
    
    try{
    connection.getInputStream();
    }
    catch (IOException exception){
    	
    	System.out.println("PRINTING ERROR STREAM");
    	DataInputStream inStream = new DataInputStream(connection.getErrorStream());
        String buffer;
        while((buffer = inStream.readLine()) != null) {
            System.out.println(buffer);
            
            throw exception;
        }
    
    	
    }
    
    System.out.println("Stra");
    
    }
    
    private Base64 base64 ; 
    private String createAuthorizationHeader(String canonicalizedString) throws InvalidKeyException, Base64DecodingException, NoSuchAlgorithmException, IllegalStateException, UnsupportedEncodingException     {  
              Mac mac = Mac.getInstance("HmacSHA256");  
              mac.init(new SecretKeySpec(base64.decode(key), "HmacSHA256"));  
              String authKey = new String(base64.encode(mac.doFinal(canonicalizedString.getBytes("UTF-8"))));  
              String authStr = "SharedKey " + account + ":" + authKey;  
              return authStr;  
         } 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    public String createDate(){
    
    SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");  
    fmt.setTimeZone(TimeZone.getTimeZone("GMT"));  
    String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
    System.out.println(date);
    return date;
    }
    
    }
    

    I have tried almost all combinations where I am not clear on what should be entered in the authorization header:

    For example klabs is my account and delete is the container.

    for Canonicalized resource, I have tried /klabs/klabs/delete     as well as /klabs/delete.

    Similarly I have tried replacing version 2009 with  2014.

    Can anyone please review this code and let me know where I might be wrong.

    The date I am printing displays GMT on console, so I ruled out that error.

    Thanks in advance.:) This is the longest it took me for a project without any results whatsoever.:(

    Thursday, August 28, 2014 7:43 PM

Answers

  • Sorry guys, to have wasted your time, I just found out my silly mistake.

    The password I was using as an input to SHA2 was "password" and not the storage account key it should have been.

    Apologies again and thanks for all those references.

    • Marked as answer by Dipanshu Verma Monday, September 1, 2014 2:51 PM
    Monday, September 1, 2014 2:51 PM

All replies

  • Hi,

    Thanks for sharing your concern.

    We're working on this and shall keep you posted with relevant reference / fix.

    Thanks,
    Arvind

    Friday, August 29, 2014 4:38 AM
  • >>><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

    Hi Dipanshu,

    Thanks for the post.

    Based on above error message, I see have not created the correct authorization header for the blob rest api request. Three things required in the request header "Authorization" and "Date or x-ms-date" and "x-ms-version". You can follow this article: http://msdn.microsoft.com/en-us/library/azure/dd179428.aspx 

    As for you are using java application client, I suggest you take a look at example below:

    http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/

    Hope it helpful, thanks.

    Best Regards


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. <br/> Click <a href="http://support.microsoft.com/common/survey.aspx?showpage=1&scid=sw%3Ben%3B3559&theme=tech"> HERE</a> to participate the survey.


    Friday, August 29, 2014 6:56 AM
  • Hi,

    In reference to the article Authentication for the Azure Storage Services:

    http://msdn.microsoft.com/library/azure/dd179428.aspx

    Please ensure to review the construction of signature string typically as specified.

    Thanks,

    Arvind

    Friday, August 29, 2014 7:32 AM
  • Hi Arvind, I have reviewed the signature quite a lot of times, will do so again. I think I am missing something very small somewhere. Can you please review it for me once. Thanks Dipanshu
    Sunday, August 31, 2014 12:34 PM
  • Hi Dipanshu,

    With your code, I see you have not specified the "x-ms-date" to your request header and the "Authorization" also needs it.

    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);

    It should be the Coordinated Universal Time (UTC). As I mentioned before, there whole examples for you to follow:

    http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/

    http://social.msdn.microsoft.com/Forums/en-US/84415c36-9475-4af0-9f52-c534f5681432/using-rest-api-to-access-azure-tables-from-windows-phone?forum=WAVirtualMachinesVirtualNetwork

    And step by step to create request authorization header for blob service rest api:

    http://msdn.microsoft.com/en-us/library/azure/dd179428.aspx

    Thanks,

    Best Regards!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. <br/> Click <a href="http://support.microsoft.com/common/survey.aspx?showpage=1&scid=sw%3Ben%3B3559&theme=tech"> HERE</a> to participate the survey.


    Monday, September 1, 2014 6:05 AM
  • Sorry guys, to have wasted your time, I just found out my silly mistake.

    The password I was using as an input to SHA2 was "password" and not the storage account key it should have been.

    Apologies again and thanks for all those references.

    • Marked as answer by Dipanshu Verma Monday, September 1, 2014 2:51 PM
    Monday, September 1, 2014 2:51 PM