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

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

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()

Azure AD access token from postman

Today, I have an issue getting an Azure AD access token from Postman. This is while it was working before for the same app and other apps I am working on. But none of them are working today.
I was working correctly, but now it shows me this error:
Error: AADSTS900144: The request body must contain the following parameter: 'client_id'
I use https://login.microsoftonline.com/common/oauth2/v2.0/authorize as auth URL, and https://login.microsoftonline.com/common/v2.0/token for Access token URL.
I have tried these for access token URL but none of them worked. https://login.microsoftonline.com/{{tenant_id}}/v2.0/token
https://login.microsoftonline.com/common/token
https://login.microsoftonline.com/{tenant_id}/token
here is my Azure AD oauth 2.0 configuration. Also, as you see, there is no client_id in the request body.
I tried to reproduce the same in my environment and got below results
You can get values of auth URL and access token URL from your Azure AD application that varies based on supported account type like below:
Go to Azure Portal -> Azure Active Directory -> App registrations -> Your App -> Overview -> Endpoints
Now I added environment variables in Postman by defining them like below:
Make sure to select the correct Environment while requesting for token with variables.
I filled the required details same as you to get the access token like below:
When I selected Get New Access Token, I got the token successfully as below:
The error usually occurs if you missed including client_id while
acquiring access token.
I changed client_id parameter to blank in variables like below:
When I tried to get access token again, I got same error as you like below:
To resolve the error, make sure to pass client_id value in right environment and save it.
I found out why it's acting like this:
I checked my friend's PC, and it was working there!
The issue was the last update of Postman. They have changed something in authorization.
just change the Client Authentication to Send client credentials in body and it will work.

Azure AD is not returning token : Unknown Host Error

I am trying to grant access to IoT Hub based on Azure AD. But when I try to get token, it is throwing this error in Postman
####### Update ######
I have already created the Application in Azure AD
The resource field should be the static ID of all IoT Hub service principals. Try this instead of the hostname:
89d10474-74af-4874-99a7-c23c2f643083
Here is another approach:
I tried to reproduce the same in my environment and got the results successfully like below:
I created an Azure AD application like below:
To generate token via Postman, I used the below parameters:
POST https://login.microsoftonline.com/TenantID/oauth2/token
client_id:14ad98e6-8b3d-4774-a2ad-XXXXX
client_secret:XXXXXX
resource:https://iothubs.azure.net
grant_type:client_credentials
Response:
When I decoded the above token, I can see the aud as https://iothubs.azure.net like below:
The 400 Bad request error usually occurs if you have passed any invalid URL while generating the token. Make sure to pass the valid parameters.
Try sending the request again in Postman and check if the access token is generated or not.
Alternatively, you can also replace the resource by 89d10474-74af-4874-99a7-c23c2f643083 as suggested by Matthijs van der Veer like below:
Decoded token Response:

Is there a way to regenerate Azure Blob Storage SAS token

I use azure-sdk-for-js (NodeJS).
Particularly - #azure/storage-blob#12.6.0.
I have a service which generates SAS tokens and they expire in few minutes. I want somehow request new tokens after previous expire. And this should be done even in the middle of operation. Because when I upload big file to blob, in the middle SAS token expires and upload fails.
I have a worked example of what I need, but with EventHub.
I create event hub client with:
new EventHubProducerClient(eventHubHost, eventHubName, sasGenerator)
And sasGenerator is emplementation of TokenCredential. It returns generated AccessToken (which have SAS token and expiresOnTimestamp). And if I got it correctly, EventHubProducerClient use my sasGenerator to refresh tokens when needed.
I found that BlobServiceClient have similar argument credential which can have type of TokenCredential. But the same approach as with EventHub doesn't work:
new BlobServiceClient(blobHost, sasGenerator)
Example of Error:
RestError: Server failed to authenticate the request. Please refer to the information in the www-authenticate header
I also was able to use generated SAS token with AnonymousCredential and it works. But I'm not able to upload big file to blob because the token expires earlier.
Please check the below points ,if they can be worked around
The error Server failed to authenticate the request. Please refer to the information in the www-authenticate header possibly may be due to an issue with your account name/key stored in the the config file or connection string.
It may be due to permissions not in correct order .See Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. And valid permission order.
Came across this Article on how to inject new SAS for an ongoing uploading .
The scenario provides sample to request a new SAS token during the uploading instead of starting a new upload.
SEE:
work-with-shared-access-signatures
Best practices using sas

List Queues/Topics of Azure Service Bus using Rest API with SharedAccessKey

I am trying to list the Queues/Topics in an Azure Service Bus using the REST API.
When I try to connect I just get back a blank feed saying "This is the list of publicly-listed services currently available".
I am using the RootManageSharedAccessKey in the portal (for dev only, I can create a more restricted key later) so it should have all the access rights that I need, I just can't seem to get it to return anything. This documentation seems to suggest that this will work, but there's no actual working examples, just theoretical responses.
I have tried doing a GET request with the signature in the URL like this:
https://myservicebusnamespace.servicebus.windows.net/$Resources/Queues;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=MYSHAREDACCESSKEY
I have also tried doing it like this:
https://myservicebusnamespace.servicebus.windows.net/$Resources
and then setting the Authorization header to
WRAP access_token="MYSHAREDACCESSKEY="
Both times I just get this back
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="text">Publicly Listed Services</title>
<subtitle type="text">This is the list of publicly-listed services currently available.</subtitle>
<id>uuid:6a5d438d-1793-451b-be41-XXXXXXXXXXXX;id=XXXXXX</id>
<updated>2020-06-28T13:03:04Z</updated>
<generator>Service Bus 1.1</generator>
</feed>
If I change the url slightly to be:
https://myservicebusnamespace.servicebus.windows.net/$Resources/Queues/
I get a slightly different response back of:
<Error>
<Code>401</Code>
<Detail>claim is empty. TrackingId:c40a2bd2-490d-4b5b-adde-33bc89aa84ff_G36, SystemTracker:myservicebusnamespace.servicebus.windows.net:$Resources/Queues, Timestamp:2020-06-28T13:27:40</Detail>
</Error>
Which seems to suggest that I am not authorised, or I am missing something. If I add an acutual queue name to the end of that url, it goes back to the original response.
I believe there is another way to get this information by using subscription ids and pem keys... using the management urls (https://management.core.windows.net/{subscription ID}/services/ServiceBus/Namespaces/{Namespace}/Topics/)
but this should all be possible using the format above, I just can't figure out the exact format required.
EDIT/UPDATE: If I don't include my auth claim, the result is exactly the same, suggesting that it's not seeing my auth claim or it's invalid. However if I include it, and just make it the token, without the WRAP bit at the start, I get an exception saying
<Error>
<Code>401</Code>
<Detail>MalformedToken: Invalid authorization header: The request is missing WRAP authorization credentials. TrackingId:7be2d7f0-c165-4658-8bf1-ea104c43defc_G28, SystemTracker:NoSystemTracker, Timestamp:2020-06-28T13:33:09</Detail>
</Error>
So it's like it's reading it then ignoring it?
If you want to list queues or topics we can use Azure service bus service rest api or Azure Resource Manager Rest API. For more details, please refer to the following steps
Azure service bus service rest api
Generate SAS token. For more details, please refer to the document
For example, I use python to create sas token
import hmac
import time
import hashlib
import base64
import urllib
sb_name='bowmantest'
// your entity path such as $Resources/topics (list topics) $Resources/queues(list queues)
topic='$Resources/topics'
url=urllib.parse.quote_plus("https://{}.servicebus.windows.net/{}".format(sb_name,topic))
sas_value='' // your share access key
sas_name='RootManageSharedAccessKey' // your share access rule name
expiry = str(int(time.time() + 10000))
to_sign =(url + '\n' + expiry).encode('utf-8')
sas = sas_value.encode('utf-8')
signed_hmac_sha256 = hmac.HMAC(sas, to_sign, hashlib.sha256)
signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest()))
auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'
auth=auth_format.format(signature,expiry,sas_name,url)
print(auth)
Call the rest API
1). list Queues
GET https://<namespace name>.servicebus.windows.net/$Resources/queues
Authorization <sas token>
2). List topics
GET https://<namespace name>.servicebus.windows.net/$Resources/topics
Authorization <sas token>
Azure Resource Manager Rest API
create a service principal and assign Azure RABC role to the sp(I use Azure CLI)
az login
#it will create a service principal and assign contributor role to the sp
az ad sp create-for-rbac -n "jonsp2"
Get Azure AD token
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=<app id>
&scope=https://management.azure.com/.default
&client_secret=<app password>
&grant_type=client_credentials
call the rest API
List Queues
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ServiceBus/namespaces/{namespaceName}/queues?api-version=2017-04-01
Authorization Bearer <AD token>

Resources