1

I get this error when trying to upload files to blob storage. The error is present both when I run on localhost and when I run in Azure Function.

My connection string looks like: DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=xxx;EndpointSuffix=core.windows.net

Authentication information is not given in the correct format. Check the value of the Authorization header. Time:2021-10-14T15:56:26.7659660Z Status: 400 (Authentication information is not given in the correct format. Check the value of Authorization header.) ErrorCode: InvalidAuthenticationInfo

But this used to work in the past but recently its started throwing this error for a new storage account I created. My code looks like below

    public AzureStorageService(IOptions<AzureStorageSettings> options)
    {
        _connectionString = options.Value.ConnectionString;
        _containerName = options.Value.ImageContainer;
        _sasCredential = new StorageSharedKeyCredential(options.Value.AccountName, options.Value.Key);
        _blobServiceClient = new BlobServiceClient(new BlobServiceClient(_connectionString).Uri, _sasCredential);
        _containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
    }
    public async Task<string> UploadFileAsync(IFormFile file, string location, bool publicAccess = true)
    {
        try
        {
            
            await _containerClient.CreateIfNotExistsAsync(publicAccess
                ? PublicAccessType.Blob
            : PublicAccessType.None);

            var blobClient = _containerClient.GetBlobClient(location);
            
            await using var fileStream = file.OpenReadStream();

            // throws Exception here
            await blobClient.UploadAsync(fileStream, true);

            return blobClient.Uri.ToString();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
    // To be able to do this, I have to create the container client via the blobService client which was created along with the SharedStorageKeyCredential
    public Uri GetSasContainerUri()
    {
        if (_containerClient.CanGenerateSasUri)
        {
            // Create a SAS token that's valid for one hour.
            var sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = _containerClient.Name,
                Resource = "c"
            };

            sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddHours(1);
            sasBuilder.SetPermissions(BlobContainerSasPermissions.Write);

            var sasUri = _containerClient.GenerateSasUri(sasBuilder);
            Console.WriteLine("SAS URI for blob container is: {0}", sasUri);
            Console.WriteLine();

            return sasUri;
        }
        else
        {
            Console.WriteLine(@"BlobContainerClient must be authorized with Shared Key 
                      credentials to create a service SAS.");
            return null;
        }
    }
3
  • 1
    How does your connection string look like? Please edit your question and include that. Please make sure to obfuscate account name and key before this information. Commented Oct 14, 2021 at 16:15
  • 1
    I faced the same issue few days ago... And instead of the usual connection string I had to provide a Shared Access Signature uri with the right authorizations as a connection string... Hope it works for you. I think azure enforced security on their storage accounts. (I also was using an Azure Function to upload files on a blob storage) Commented Oct 14, 2021 at 16:19
  • @Flo could you share me a sample of your code please? Commented Oct 14, 2021 at 17:12

1 Answer 1

1

Please change the following line of code:

_blobServiceClient = new BlobServiceClient(new BlobServiceClient(_connectionString).Uri, _sasCredential);

to

_blobServiceClient = new BlobServiceClient(_connectionString);

Considering your connection string has all the necessary information, you don't really need to do all the things you're doing and you will be using BlobServiceClient(String) constructor which expects and accepts the connection string.

You can also delete the following line of code:

_sasCredential = new StorageSharedKeyCredential(options.Value.AccountName, options.Value.Key);

and can probably get rid of AccountName and Key from your configuration settings if they are not used elsewhere.

Sign up to request clarification or add additional context in comments.

5 Comments

I actually have another function that generates a SaSUrl for the container which the frontend app will use to upload larger files directly to the blob storage. To be able to generate a SaSUrl for the container I need to create the container client in the way I did
I’m not sure I understand your comment. Can you please edit your question and provide more details. Thanks.
I create the _containerClient in the way I do because I need to be able to generate a SaSUri for the container. To be able to do that, the container client must be created via blobService which is created with a StorageSharedKeyCredential
Understood. However if your connection string includes the credentials, then you don’t need to include it separately using StorageSharedKeyCredential.
This worked. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.