none
Get Authentication error when put object to Azure storage RRS feed

  • Question

  • I am using java to make a REST Api call to Azure, put an object to its storage. I did this successfully last week but now its now working for some reasons. The error message is as below:

    <?xml version="1.0" encoding="utf-8" ?>
    <Error>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:a15f2626-0001-004f-778c-f34383000000 Time:2017-07-02T23:43:20.2826278Z</Message>
    <AuthenticationErrorDetail>The Date header in the request is incorrect.</AuthenticationErrorDetail>
     </Error>

    I don't think this is caused by the incorrect time stamp because the "Date" field and the response time are within 15 minutes. The "Date" field in the header is Sun, 2 Jul 2017 23:38:04 GMT Here are my java code to generate the token and send the request.

     public void putObject(String blobName) {
        try {
            URL restServiceURL = new URL(getCallAddress() + "/" + blobName);
            HttpURLConnection httpConnection = (HttpURLConnection) restServiceURL.openConnection();
    
            Calendar cd = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            String date = sdf.format(cd.getTime());
    
            httpConnection.setDoInput(true);
            httpConnection.setDoOutput(true);
            try {
                httpConnection.setRequestMethod("PUT");
            } catch (ProtocolException e) {
                e.printStackTrace();
            }
            httpConnection.setFixedLengthStreamingMode(getFile().length()); //set output size to avoid out of memory error
    
          try {
            String token = createToken(blobName, date);
            httpURLConnection.setRequestProperty("Authorization", "SharedKey " + Azure_AccountName + ":" + token);
            } catch (Exception e) {
                log.error("Cannot get token");
                e.printStackTrace();
            }
    
            httpURLConnection.setRequestProperty("Content-Length", String.valueOf(getFile().length()));
            httpURLConnection.setRequestProperty("x-ms-blob-type", "BlockBlob");
            httpURLConnection.setRequestProperty("x-ms-version", "2015-12-11");
            httpURLConnection.setRequestProperty("x-ms-date",date);
            } catch (IOException e) {
                log.error(e);
                e.printStackTrace();
        }
    
        FileInputStream inputStream = new FileInputStream(getFile());
        try {
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            OutputStream out = httpConnection.getOutputStream();
            out.write(buffer);
            out.flush();
            out.close();
    
            int code = httpConnection.getResponseCode();
            if (code != 201 && code != 200) {
                log.error(code + httpConnection.getResponseMessage());
                throw new UnsupportedOperationException("Put object failed");
            }
            httpConnection.disconnect();
    
        } catch (Exception e) {
            log.error(e);
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }
    
    private String createToken(String blobName, String date) throws InvalidKeyException, NoSuchAlgorithmException,
            UnsupportedEncodingException {
        String signature = "PUT\n\n\n" + getFile().length() + "\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:" + date +
                "\nx-ms-version:2015-12-11\n" + "/" + Azure_AccountName + "/" + Azure_BucketName + "/" + blobName;
        SecretKey secreteKey = new SecretKeySpec(Base64.decode(KEY), "HmacSHA256");
        Mac sha256HMAC = Mac.getInstance(secreteKey.getAlgorithm());
        sha256HMAC.init(secreteKey);
        byte[] digest = sha256HMAC.doFinal(signature.getBytes("UTF8"));
        return new String(Base64.encode(digest));
    }

    Can anyone help me with this, I would be very appreciate, I've got stuck on this for several days... Very confused. Thanks!

    Monday, July 3, 2017 9:10 PM

All replies

  • It's unclear to me that this is an Azure Functions (AF) issue. The code you provided isn't AF specific at all. Are you running this as an AF? If so, you might consider debugging outside of AF to find out where your auth code bug might be.

    Mathew Charles [MSFT]


    Wednesday, July 5, 2017 6:54 PM
  • I think I asked this in a wrong forum...

    I will ask in storage forum instead

    Thursday, July 6, 2017 7:07 PM