Azure SAS token AuthorizationResourceTypeMismatch - azure

I have created azure storage account. I have created file storage. I have generated SAS token. when I try to access file using sas token showing error "The remote server returned an error: (403) Forbidden."
I am able to generate SAS token. when I try to access file in file storage throwing exception. I have tried to copy and paste url on browser throws error "
<Error>
<Code>AuthorizationResourceTypeMismatch</Code>
<Message>
This request is not authorized to perform this operation using
this resource type. RequestId:4cbc0cbe-401a-00c2-2edf-
202bc4000000 Time:2019-06-12T05:26:39.4816687Z
</Message>
</Error>"
Code I am using to Generate SAS token
Static string GetAccountSASToken()
SharedAccessAccountPolicy policy = new
SharedAccessAccountPolicy()
{
Permissions = SharedAccessAccountPermissions.Read |
SharedAccessAccountPermissions.Write |
SharedAccessAccountPermissions.List,
Services = SharedAccessAccountServices.File,
ResourceTypes = SharedAccessAccountResourceTypes.Service,
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
Protocols = SharedAccessProtocol.HttpsOnly,
};
Code I am using to access file
XDocument objdoc = XDocument.Load(filepath+ sasToken);
After loading file to XDocument I have to perform some read and write operations.Please help in finding mistake that I am doing

I was encountering the same problem, and the solution from user3404686 (2019-07-13) is correct. After the fact it's much clearer, but when it's still a problem without resolution it can be baffling.
Resource types are authorised independently of each other, rather than there being a hierarchy, ie 'service' does not include 'container' and 'object' authorisations (which was my misunderstanding).
The storageservices API documentation describes how resource type permissions are assigned:
Service (s): Access to service-level APIs (e.g., Get/Set Service Properties, Get Service Stats, List Containers/Queues/Tables/Shares)
Container (c): Access to container-level APIs (e.g., Create/Delete Container, Create/Delete Queue, Create/Delete Table, Create/Delete
Share, List Blobs/Files and Directories)
Object (o): Access to object-level APIs for blobs, queue messages, table entities, and files(e.g. Put Blob, Query Entity, Get Messages,
Create File, etc.)
Further down in the same document, it provides examples of the service, resource type and permissions required for various operations that you may be using, allowing minimum-required-permissions granularity with regard to assigning permissions to a service using the SA token.
After understanding this, the error code AuthorizationResourceTypeMismatch makes more sense - the resource type(s) the SAS token is authorised for, mismatches the resource types you're attempting to access.

In SharedAccessAccountPolicy I have changed
ResourceTypes =SharedAccessAccountResourceTypes.Service to
ResourceTypes = SharedAccessAccountResourceTypes.Object. Then It's working for me.

Related

AzureBlobStorage fails when enumerating Pageable<BlobContainerItem> result from GetBlobContainers with RequestFailedException, not authorized

I am building an infrastructure wrapper around Azure Blob Storage for a shared component in a .Net Core 6 suite of applications, both web and desktop-based applications. I’m using version 12.14.1 of Azure.Storage.Blobs.
public BlobContainerItem[] GetContainers(string sasToken)
{
blobUri = "https://spiffyaccountname.blob.core.windows.net?" + sasToken;
var client = new BlobServiceClient(blobUri);
var containers = client.GetBlobContainers(); // Succeeds!
var array = containers.array() // Fails with Azure.RequestFailedException
return array;
}
Exception Details:
Azure.RequestFailedException: This request is not authorized to perform this operation using this resource type.
RequestId:...
Time:...
Status: 403 (This request is not authorized to perform this operation using this resource type.)
ErrorCode: AuthorizationResourceTypeMismatch
I don't think it's a code issue but rather a configuration issue, as creating and deleting containers work fine, though I haven't been able to find the setting to fix it.
More than likely the reason you are getting this error is because of incorrect permissions in your SAS token.
Please check for 2 things:
Use Account SAS - Listing containers require that you use Account SAS instead of Service SAS.
Use proper permissions - Listing containers require that your account SAS has SignedServices as Blob (ss=b), SignedResourceTypes as Service (srt=s) and SignedPermission should have at least List permission (sp=l).

Getting a blob content using user delegation SAS created using user delegation key

I have created an AAD app as per https://learn.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app.
The access is given to the azure storage account for the AAD app created.
Got the client id and client secret.
To create a user delegation key and user delegation sas, I am using the approach and code as defined in
https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-user-delegation-sas-create-dotnet.
(set environment variables as mentioned in article).
I am able to generate the user delegation key using method GetUserDelegationSasBlob.
The container and blob file is existing one.
Now I am using the method ReadBlobWithSasAsync to read the contents of the blob using the SAS uri as generated above.
But, I get error as below.
This request is not authorized to perform this operation using this
permission. RequestId:5d127eaf-101e-00be-6666-6a3875000000
Time:2019-09-13T19:04:15.4109144Z
Status: 403 (This request is not authorized to perform this operation
using this permission.)
ErrorCode: AuthorizationPermissionMismatch
In another approach, I am generating the user delegation key using rest api.
https://learn.microsoft.com/en-us/rest/api/storageservices/get-user-delegation-key
I am able to get user delegation key in xml format.
I am creating SAS from it as per steps in
https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas
For signature, I am using this code, using StringToSign and secret value as received from delegation key.
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(ToSign);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
String sig= Convert.ToBase64String(hashmessage);
}
I am doing the GET request.
I have tried various set of parameter values, like,
sr: b and c
sks: b and c
sp: racwd and r and rw and few more
skv and sv is 2018-11-09 because this version is required for creating user delegation key.
But the GET api returns the error.
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the
signature. RequestId:e4bc8f0f-d01e-0046-7367-6af368000000
Time:2019-09-13T19:12:27.7780695Z
Signature fields not well formed.
Try to assign the Storage Blob Data Contributor role to the storage account.
The Reader role is an Azure Resource Manager role that permits users to view storage account resources, but not modify them. It does not provide read permissions to data in Azure Storage, but only to account management resources.
Refer to this article.

Unable to Get/Post Blob on Azure Storage via Rest API in C#

Upon successful consumption of Azure Rest api in c# code. I'm able to create, fetch and fetch list of containers but not blob. While accessing or uploading blobs, this gives permission issue and i.e.,
you are not authorized to perform this request with assigned permission
Progress that i have made so far:
Able to create and fetch the container.
Able to fetch the list of all the containers of storage account.
When tries to Get/Put a blob via below source code it give me error:
This request is not authorized to perform this operation using this permission.
string endPointUri = $"{azureApplicationConfiguration.Resource}/{inpContainerName}/{inpBlobName}";
var request = (HttpWebRequest)WebRequest.Create(endPointUri);
request.Method = HTTPMethod.GET.ToString();
request.Headers.Add("Authorization", $"Bearer {sasToken.access_token}");
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R"));
request.Headers.Add("x-ms-version", "2018-03-28");
request.ProtocolVersion = HttpVersion.Version11;
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
Console.WriteLine(resp.StatusCode.ToString());
Console.ReadKey();
}
The most likely answer is that the SAS token you're using to authenticate does not support object level access. You can confirm this by checking if there is a letter o in the Signed Resource Types srt= parameter in your SAS token. Based on the fact you can list and create containers, I'd guess the current value is srt=sc. To be able to perform GET/PUT operations on a blob as well, you'll need to generate a new SAS token that includes object level permissions, which should give you a token containing srt=sco.
In case you aren't aware of it already, there is a .NET Azure Storage SDK available, which provides a layer of abstraction over the REST API and may save you some time in the long run.

Authorization Token accessing Cosmos DB document

I am trying to login with username and password using Azure AD B2C with MSAL. After logging in, we are authenticating access token using web API which returns the resource token and after getting it we connect the DocumentClient using resource token as mentioned below, but when we try to perform the action like savedocument in Cosmos DB, facing following error
var Client = new DocumentClient(new System.Uri(App.accURL), resourceToken);
Message:
{"Errors": ["Authorization Token doesn't present sufficient permissions to serve the request."]}
ActivityId: 3360415e-b937-4061-b74d-485d44550df2,
Request URI: /apps/7dc938ac-8c47-4af3-9760-5e80284624b0/services/4344f786-4b9a-4293-ab0a-d27a5ccae76a/partitions/26b66fff-1ad2-47dc-90c8-cc9ee7b0d23b/replicas/131448621059935679p: Error: ...
when we try to perform the action like savedocument in cosmosDB, facing following error. Authorization Token doesn't present sufficient permissions to serve the request.
AFAIK, we can associate only one permission to a specific resource for a user. And there are only two permission modes: All (Read, write, delete permissions) or Read. I would recommend you checking the permissionMode, ResourceLink, ResourceTokenExpirySeconds if you specified for your user have correctly configured.
You could List Permissions for a user and use DocumentClient.ReadPermissionFeedAsync for retrieving the permissions for a user. Additionally, you could refer to the related tutorials Permissions in Azure DocumentDB and Cosmos DB > Permissions.
If you still could not locate this issue, please updated your question with the related code for granting permission for your user and leverage fiddler to collect the network traces when using the resourceToken token for accessing resources.

How do I set the shared access policy for an Azure Queue?

Apparently access to Azure queues can be controlled using a Shared Access Policy. The example here http://msdn.microsoft.com/en-us/library/windowsazure/hh508996 confirms this, but then only provides an example for a blob shared access policy. Does anyone have any references on how the same is achieved for Queues (and Tables)?
You can find the complete sample on the Windows Azure Storage blog: Introducing Table SAS (Shared Access Signature), Queue SAS and update to Blob SAS. Here is the part that assigns the policy to a queue:
// Create the GC queue SAS policy.
QueuePermissions gcQueuePermissions = new QueuePermissions();
SharedAccessQueuePolicy gcQueuePolicy = new SharedAccessQueuePolicy()
{
// Providing the max duration
SharedAccessExpiryTime = DateTime.MaxValue,
// Permission is granted to process queue messages.
Permissions = SharedAccessQueuePermissions.ProcessMessages
};
// Associate the above policy with a signed identifier
gcQueuePermissions.SharedAccessPolicies.Add(
gcPolicySignedIdentifier,
gcQueuePolicy);
// The below call will result in a Set Queue ACL request to be sent to
// Windows Azure Storage in order to store the policy and associate it with the
// "GCAccessPolicy" signed identifier that will be referred to
// by the generated SAS token
this.gcQueue.SetPermissions(gcQueuePermissions);
Does the announcement post for table SAS (especially the SAS token producer portion of the sample) can help you any way? It seems to me the SAS is available on Table and Queues starting with SDK 1.7.

Resources