Azure blob storage - upload blob using REST API and shared key authorization header in postman
In this blog, we will see steps on how to create an authorization header using an Azure storage account shared key and upload a file using Postman. Official documentation for put blob operation is available at the below link-
https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob
Firstly, create four environment variables in Postman as follows-
Populate the name of storage account in azure_storage_account where you want to upload a file. This storage account name will be used in the request directly.
Go to your storage account > Access keys and copy any of the key. Populate this key value in variable azure_storage_key-
Other two variables- header_date and header_authorization will be populated at runtime.
Create a new PUT request "Azure blob storage- upload file" with below url.
https://{{azure_storage_account}}.blob.core.windows.net/<container_name>/<filePath>
It will look something like below-
In this url, {{azure_storage_account}} will read storage account name from environment variable, test is name of my container and newFolder/newFile.txt is my file path where I want to upload my file.
Go to request body tab, select raw, format as text and add some file content that you want to upload.
If you want to upload a file then instead of raw, select binary and you will be able to browse file and select as body.
Go to request header tab and add below headers. For x-ms-date and Authorization, we are using environment variable values which will be calculated in next step. Content-Length is a mandatory header parameter but Postman will automatically add it, so no need to add explicitly.
Now, go to Pre-request Script tab and add below javascript code to it. This code will run before sending request, calculates and stores x-ms-date and Authorization values.
Note that this script uses environment variables mentioned above, so make sure those variables are created and populated correctly.
A detailed explanation about how this Authorization header is calculated can be found with below link-
https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key
// Set Date header value for authorization // Should be UTC GMT string pm.variables.set("header_date", new Date().toUTCString()); // Get hash of all header-name:value const headers = pm.request.getHeaders({ ignoreCase: true, enabled: true }); // Construct Signature value for Authorization header var signatureParts = [ pm.request.method.toUpperCase(), headers["content-encoding"] || "", headers["content-language"] || "", headers["content-length"] || "", // pm.request.body ? pm.request.body.toString().length || "" : "", headers["content-md5"] || "", headers["content-type"] || "", headers["x-ms-date"] ? "" : (pm.variables.get("header_date") || ""), headers["if-modified-since"] || "", headers["if-match"] || "", headers["if-none-match"] || "", headers["if-unmodified-since"] || "", headers["range"] || "" ]; // Construct CanonicalizedHeaders const canonicalHeaderNames = []; Object.keys(headers).forEach(key => { if (key.startsWith("x-ms-")) { canonicalHeaderNames.push(key); } }); // Sort headers lexographically by name canonicalHeaderNames.sort(); const canonicalHeaderParts = []; canonicalHeaderNames.forEach(key => { let value = pm.request.getHeaders({ ignoreCase: true, enabled: true })[key]; // Populate variables value = pm.variables.replaceIn(value); // Replace whitespace in value but not if its within quotes if (!value.startsWith("\"")) { value = value.replace(/\s+/, " "); } canonicalHeaderParts.push(`${key}:${value}`); }); // Add headers to signature signatureParts.push.apply(signatureParts, canonicalHeaderParts); // Construct CanonicalizedResource const canonicalResourceParts = [ /${pm.variables.get("azure_storage_account")}${pm.request.url.getPath()} ]; const canonicalQueryNames = []; pm.request.url.query.each(query => { console.log("query", query); canonicalQueryNames.push(query.key.toLowerCase()); }); canonicalQueryNames.sort(); canonicalQueryNames.forEach(queryName => { const value = pm.request.url.query.get(queryName); // NOTE: This does not properly explode multiple same query params' values // and turn them into comma-separated list console.log("queryName", queryName); console.log("value", value); canonicalResourceParts.push(`${queryName}:${value}`); }); // Add resource to signature signatureParts.push.apply(signatureParts, canonicalResourceParts); console.log("Signature Parts", signatureParts); // Now, construct signature raw string const signatureRaw = signatureParts.join("\n"); console.log("Signature String", JSON.stringify(signatureRaw)); // Hash it using HMAC-SHA256 and then encode using base64 const storageKey = pm.variables.get("azure_storage_key"); const signatureBytes = CryptoJS.HmacSHA256(signatureRaw, CryptoJS.enc.Base64.parse(storageKey)); const signatureEncoded = signatureBytes.toString(CryptoJS.enc.Base64); // Finally, make it available for headers pm.variables.set("header_authorization",`SharedKey ${pm.variables.get("azure_storage_account")}:${signatureEncoded}`);
Request setup is ready to upload file. Hit send button on request and you will get 201 created response as below. You can go to blob container and verify that newFile.txt is created.
Thanks for reading.
Keep learning!