I have a process that generates a SAS Uri to be used to upload some files to Azure storage. Right now it is using the older "Microsoft.Azure.Storage" packages because I am using the Microsoft.Azure.Storage.DataMovement.dll for it's ease of uploading large files.
When I use the SAS Uri in Storage Explorer everything works great. It also works fine if I don't check if the container exists, but doing the exists check causes a permissions error. I've tried giving the application that generates the SAS all permissions in the IAM role, but it still happens.
var sasUri = @"<sas uri>";
var backupsContainer = new Microsoft.Azure.Storage.Blob.CloudBlobContainer(new Uri(sasUri));
backupsContainer.Exists();
That is the code snippet that gives me the 'This request is not authorized to perform this operation' error.
I've looked at similar questions: This request is not authorized to perform this operation. Azure blobClient but I don't have any firewall rules in place.
I should mention, previously I was generating the SAS using the storage account's keys. When I updated it to instead use an application is when it broke. I updated it because eventually I want it to use the Managed Identity credentials. I've included the code that generates the SAS as well
BlobSasBuilder blobSasBuilder = new BlobSasBuilder
{
BlobContainerName = ExportSASInfo.ExportContainerName,
//c for container
Resource = "c",
// Access expires in 2 hours
ExpiresOn = DateTimeOffset.UtcNow.AddHours(sasSettingsModel.SasExpirationHours)
};
//allow adding blobs
blobSasBuilder.SetPermissions(
BlobContainerSasPermissions.Read
| BlobContainerSasPermissions.Add
| BlobContainerSasPermissions.Create
| BlobContainerSasPermissions.Write
| BlobContainerSasPermissions.Delete
| BlobContainerSasPermissions.List);
string scheme = "https";
string host = $"{customerInfo.AzureStorageAccountName}.blob.core.windows.net";
string blobEndpoint = $"{scheme}://{host}";
DefaultAzureCredential azureCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions() { ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true, ExcludeSharedTokenCacheCredential = true });
BlobServiceClient blobServiceClient = new BlobServiceClient(
serviceUri: new Uri(blobEndpoint),
credential: azureCredential);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(ExportSASInfo.ExportContainerName);
await containerClient.CreateIfNotExistsAsync();
UserDelegationKey key = await blobServiceClient.GetUserDelegationKeyAsync(
startsOn: DateTimeOffset.UtcNow.AddMinutes(-5),
expiresOn: DateTimeOffset.UtcNow.AddHours(sasSettingsModel.SasExpirationHours)); var sasToken = blobSasBuilder.ToSasQueryParameters(
userDelegationKey: key,
accountName: customerInfo.AzureStorageAccountName);
BlobUriBuilder blobUriBuilder = new BlobUriBuilder(containerClient.Uri)
{
Sas = sasToken
};
return new ExportSASInfo() { sasUri = blobUriBuilder.ToUri() };
Your roles are enough, I can also reproduce your issue, because what you generated is a container level SAS, to check the existence of this container, the SAS needs permission to list all the containers in the account i.e. the account level SAS, no matter what role is your MSI(managed identity) and the permissions in blobSasBuilder.SetPermissions()
, it will not work.
In your case, you use MSI to auth and create the user delegation SAS, it is not supported to create the account level SAS, it can be just signed with the storage account key, so if you want to check the existence of the container, your option is to use the ExistsAsync
method directly.
string blobEndpoint = string.Format("https://{0}.blob.core.windows.net","joystoragev2");
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(blobEndpoint), new ManagedIdentityCredential());
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("test");
containerClient.ExistsAsync().GetAwaiter().GetResult();
Note: In my screenshot, I test it with EnvironmentCredential
in local, if you want to use MSI to auth, just replace it with ManagedIdentityCredential
like the code above, also make sure you are running the code in the Azure Environment with MSI enabled e.g. web app, then it will work fine.
After this, you could use the SAS to do operations on the container, e.g. upload large files.