Creating an Azure Blob Container using a SAS - azure

I'm trying to create a new container in a Blob Storage account using the Create Container API.
https://myaccount.blob.core.windows.net/mycontainer?restype=container
I can't get this to work, I'm struggling to get the format of the Authorization header right. Other blob services I've used allow this to be passed as a query parameter.
I have the SAS token, similar to ?sv=2019-12-12&ss=bfqt&srt=sco&sp=rwdlacupx&se=2022-02-01T16:52:59Z&st=2021-02-02T08:52:59Z&spr=https&sig=r4%2B7dlSfSO8kyd8mKawHhXNtRzInq7YI%2FIbqSr1g%2FqE%3D
How do I form the Authorization header correctly to pass this?
Thanks.

To create a blob container by using Create Container rest api, if you're using "sas token", then you don't need to add "Authorization" in the Headers.
Assume you have a correct "sas token", then you the request url should look like this(Note: you should remove the first "?" from the "sas token"):
https://myaccount.blob.core.windows.net/mycontainer?restype=container&your_sas_token(note that remove the first ? from sas token)
And in the Headers, you just need pass x-ms-date and x-ms-version.
Here is the test by using Postman:
By the way, here is the screenshot about how to generate the "sas token" for creating blob container:

Related

Generate/retrieve a SAS token programmatically for specific Blob/File under azure storage account via REST API in POSTMAN and then in IBM APP Connect

I have requirement where it has to be done programmatically using POSTMAN REST API, where I have to upload a file/blob to Azure storage account and retrieve the unique URL of the specific file that I have uploaded, and I have to share that URL to third party so that they can view it on browser.
This is what I have done in the POSTMAN
Request:
PUT https://{storage-account-name}.blob.core.windows.net/{container-name}/{file-name}{SAS-token}
Headers:
x-ms-version: 2020-04-08
x-ms-blob-type: BlockBlob
x-mock-response-name: Upload Blob
Body: Attached a file from my local
Response:
I have received 200 code and file is successfully uploaded. However, in the response headers I don't see any URL or unique SAS token that I can share to my third-party client.
I have also tried adding se and sp to sas token, I got the below error
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:65282b4e-401e-0050-2337-43ee90000000 Time:2023-02-18T01:20:28.3522177Z
**Signature did not match. String to sign used was r 2023-02-18T09:12:15Z /blob/storage-account-name/container-name/file-name.txt 2021-06-08 b **
Note: We don't want to generate SAS token manually from Azure portal for each file and construct the URL and share it to the client due to high traffic coming in. Once it is successful using POSTMAN. I have to implement the same in IBM App Connect enterprise, ESQL coding*
All the suggestions are much appreciated. Thank you in advance.
Retrieve the unique URL of the specific file that I have uploaded programmatically and share that URL with third party so that they can view it on browser.
In addition to the se and sp parameters, the following parameters are required to construct the correct SAS URL:
signed version (sv)
signed resource (sr)
signature
Your error message says that the signature does not match the rest of the URL. Signature a hash-based message authentication code (HMAC) that you compute over the string-to-sign and key by using the SHA256 algorithm, and then encode by using Base64 encoding
You can find how to construct the string-to-sign and signature depending on the version on this documentation page.
Postman has a built-in JavaScript library that can help you to calculate HMAC:
CryptoJS.HmacSHA1("string-to-sign", "key").toString()

How to Access Azure Table Storage using Shared Access Key in Postman?

I use the SAS key to make a GET request for the table, but I get the error "This request is not authorized to perform this operation.". What values should I fill in on the authorization tab to work this out?
enter image description here
x-ms-blob-type and BlobBlock work for blob storage but I need key and value for table type.
If you are using SAS, you don't need any API key. Set Authorization to 'Inherit Auth from Parent'.
Below are the settings I used to get my Table SAS.
And below are the settings in my Postman
The url I used for my query was https://anumystorage.table.core.windows.net/mytable(PartitionKey='A',RowKey='B')<your_sas_token> <-- Replace <your_sas_token> with your own Sas starting with '?sv=.....'
The information on the Table storage Rest API can be found here.
I tried to reproduce the same in my environment and got the below results successfully:
I created an Azure Storage Account and created Table storage:
I generated SAS URL by checking the below options:
Copy the Azure Table Storage SAS:
To access the Azure Table Storage, include the Table Storage Name like below:
https://StorageAccount.table.core.windows.net/TableStorage?TableSASUrl
Response:

Get Azure Storage to Return blob URL when listing storage container contents

I'm trying to use a service principal to access and list the contents of an Azure storage container using PowerShell. I've been able to get a token for the service principal and use that to access the storage account but when I run this command
$iwrParams = #{
'Uri' = 'https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list'
'UseBasicParsing' = $true
'ContentType' = 'application/xml'
'Headers' = #{
'Authorization' = "Bearer $($token.access_token)"
'x-ms-version' = '2017-11-09'
}
}
Invoke-WebRequest #iwrParams
I get a return from this but the return xml content never shows the URL for each returned blob. If you look at the return at https://learn.microsoft.com/en-us/rest/api/storageservices/enumerating-blob-resources#list-blobs-and-snapshots it shows that for each blob it should return a Name, Url and various other properties. When I run the code above I get everything but the Url.
Now the really interesting thing is if I change the container access to anonymous public and run this code, I get the Url returned as expected.
$iwrParams = #{
'Uri' = 'https://myaccount.blob.core.windows.net/mycontainer?comp=list'
'UseBasicParsing' = $true
'ContentType' = 'application/xml'
}
Invoke-WebRequest #iwrParams
The issue honestly seems to be having to include restype=container when accessing with any sort of authentication.
My question is does anyone know a way to get the URL for each blob returned when not using anonymous access to list container contents?
I'd like to do this without resorting to the Az modules.
The reason you're not able to see the URL returned in the response is because of the storage REST API version used by your code (2017-11-09). Essentially the Blob URL property was removed from the response starting with REST API version 2013-08-15. From this link:
In version 2013-08-15 and newer, the EnumerationResults element
contains a ServiceEndpoint attribute specifying the blob endpoint, and
a ContainerName field specifying the name of the container. In
previous versions these two attributes were combined together in the
ContainerName field. Also in version 2013-08-15 and newer, the Url
element under Blob has been removed.
Regarding your comment about why you can see the URL property if you list blobs anonymously, this is happening because if no REST API version is specified in the request, Storage Service uses the oldest REST API version to process the request if default version has not been set. From this link:
If an anonymous request to a general-purpose storage account does not
specify the x-ms-version header, and the default version for the
service has not been set using Set Blob Service Properties, then the
service uses the earliest possible version to process the request.
Considering you would want to use Azure AD based authorization, the earliest version you will be able to use is 2017-11-09 thus it will not be possible to get the Blob URL returned in the response body.
One option would be to manually construct the Blob URL by using Blob Container URL and Blob name. Other option would be to use Shared Key Authorization instead of Azure AD authorization and specifying a version earlier than 2013-08-15 for x-ms-version request header in your requests. You will need to manually compute Authorization header value in this case using instructions provided here.

Azure SAS | Error | Make sure the value of Authorization header is formed correctly including the signature

I have got details to send data to Azure SAS.
Storage Account Name: acountname123
Blob Container Name - containername123
SAS URI:
https://acountname123.blob.core.windows.net/containername123?sv=2019-12-12&si=xxinboundpolicy&sr=c&sig=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I tried to call this from soapui however its giving error related to authorization header.
Can you pl help me with what I need to pass in authorization header.
I followed below links
https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob
https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview?toc=%2fazure%2fstorage%2fblobs%2ftoc.json
Thanks
Yatan

Python: Upload a package to Azure using SAS URI

I am using the Microsoft's Hardware dashboard API to automate the submission of my (.CAB) package for signing. I have followed the steps in this documentation: https://learn.microsoft.com/en-us/windows-hardware/drivers/dashboard/create-a-new-submission-for-a-product
The response of new submission contains the SAS(Shared Access Signature) URI
like this: (changed the sig and accnt_name for security)
'''https://accnt_name.blob.core.windows.net/scsjc/cexxxxxxxxxx?sv=2017-04-17&sr=b&sig=xxxxxxxxxxxxxx&se=2019-07-10T18:15:58Z&sp=rwl&rscd=attachment%3B filename%3Dinitial_xxxxxxxx.cab'''
I need to use this SAS URI to upload by package to azure blob storage.
The examples in documentation shows C# or .NET as follows:
string sasUrl =
"https://productingestionbin1.blob.core.windows.net/ingestion/26920f66-
b592-4439-9a9d-fb0f014902ec?sv=2014-02-
14&sr=b&sig=usAN0kNFNnYE2tGQBI%2BARQWejX1Guiz7hdFtRhyK%2Bog%3D&se=2016-
06-17T20:45:51Z&sp=rwl";
Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob blockBob =
new Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob(new
System.Uri(sasUrl));
await blockBob.UploadFromStreamAsync(stream);
I want to use the SAS URI obtained from submission resource JSON Response to upload the package.
This link Download file from AZURE BLOB CONTAINER using SAS URI in PYTHON suggests that there is no equivalent method in python and BlockBlobService can be used.
from azure.storage.blob import BlockBlobService
blobservice = BlockBlobService("storage_account",sas_token="?sv=2018-03-
28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-04-24T10:01:58Z&st=2019-04-
23T02:01:58Z&spr=https&sig=xxxxxxxxx")
blobservice.create_blob_from_path(container_name, local_file_name,
full_path_to_file)
However I am not sure of what is storage_account name and container name from the SAS URI obtained from submission resource.
Also I have created a separate azure storage account and added a new container, blob in it. I have tried passing the new container and storage account name with SAS access token from SAS URI (obtained from submission JSON response micorsoft hardware api) but always get below ERROR
'''
AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ErrorCode: AuthenticationFailed
AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:5463b7d2-901e-0068-6994-36782e000000
Time:2019-07-09T20:23:04.5760736ZSignature did not match. String to sign used was rwl
2019-07-10T18:15:58Z
/blob/evcertautomation/ev2/initial_1152921504628106590.cab
2017-04-17
attachment; filename=initial_1152921504628106563.cab
'''
Thanks in advance
If you have a blob SAS URI as you post below, you can easily upload a file to the blob in Python with requests.
https://accnt_name.blob.core.windows.net/scsjc/cexxxxxxxxxx?sv=2017-04-17&sr=b&sig=xxxxxxxxxxxxxx&se=2019-07-10T18:15:58Z&sp=rwl&rscd=attachment%3B filename%3Dinitial_xxxxxxxx.cab
First, you must have to inspect the values of parameters se and sp. The se parameter means the expire time of the blob SAS URI, and the sp parameter means the operation permisson of the blob SAS URL like w for Blob Write Permission
So for your blob SAS URL above, you have the blob write permission to upload a file to this blob before the time 2019-07-10T18:15:58Z.
Here is my sample code for uploading via a blob sas uri.
import requests
blob_sas_uri = '<your blob sas uri which must includes `sp=w` and do the write operation before `se`>'
local_file_name = '<your local file name>'
headers = {
'x-ms-blob-type': 'BlockBlob'
}
data = open(local_file_name).read()
r = requests.put(blob_sas_uri, headers=headers, data=data)
print(r.status_code)
If you see the result is 201, it works fine and succeed for uploading.
As reference, there is a similar offical sample Example: Upload a Blob using a Container’s Shared Access Signature which using a wide container permission.
As per the SAS URI you provided: '''https://accnt_name.blob.core.windows.net/scsjc/cexxxxxxxxxx?sv=2017-04-17&sr=b&sig=xxxxxxxxxxxxxx&se=2019-07-10T18:15:58Z&sp=rwl&rscd=attachment%3B filename%3Dinitial_xxxxxxxx.cab'''
The account name should be accnt_name, the container should be scsjc.
So your code should look like below:
from azure.storage.blob import BlockBlobService
storage_account ="accnt_name"
token="?sv=2018-03-
28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-04-24T10:01:58Z&st=2019-04-
23T02:01:58Z&spr=https&sig=xxxxxxxxx"
container="scsjc"
blobservice = BlockBlobService(storage_account,sas_token=token)
blobservice.create_blob_from_path(container, local_file_name,
full_path_to_file)

Resources