Getting Error while Creating SAS Token for Azure Storage Blob with MSI

I'm trying to create a SAS token for a storage blob. I use a StorageCredentials which was created with MSI (Managed Service Identity) to create the CloudBlobClient. When creating the SAS I'm getting "Cannot create Shared Access Signature unless Account Key credentials are used". Is there support to SAS with MSI?

var container = blobClient.GetContainerReference(containerName);
var blockBlob = container.GetBlockBlobReference(snapname);
var sas = string.Concat(blockBlob.Uri.ToString(), blockBlob.GetSharedAccessSignature(sasConstraints));

This is how I create the StorageCredentials:

tokenCallback = CreateMsiCallback();
var initToken = await tokenCallback(audience);
return new StorageCredentials(
  new TokenCredential(initToken, async (state, token) =>
  {
    var accessToken = await _tokenCallback(audience);

    return new NewTokenAndFrequency(accessToken, TimeSpan.FromMinutes(1));
  }, null, TimeSpan.FromMinutes(1))
);

To create the token callback I use HttpClient

public Func<string, Task<string>> CreateMsiCallback()
{
  var handler = new HttpClientHandler
  {
     ServerCertificateCustomValidationCallback =
         (httpRequestMessage, cert, certChain, policyErrors) =>
         {
             if (policyErrors == SslPolicyErrors.None)
             {
                 return true;
             }

             return 0 == string.Compare(cert.GetCertHashString(), FabricThumbprint, StringComparison.OrdinalIgnoreCase);
        }
  };

     var client = new HttpClient(handler)
     {
         DefaultRequestHeaders =
         {
            {"secret", FabricAuthenticationCode }
         }
     };

     return async (resource) =>
     {
            var requestUri = $"{FabricMsiEndpoint}?api-version={FabricApiVersion}&resource={HttpUtility.UrlEncode(resource)}";
            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUri);
            var response = await client.SendAsync(requestMessage);
            response.EnsureSuccessStatusCode();
            var tokenResponseString = await response.Content.ReadAsStringAsync();
            var tokenResponseObject =
                JsonConvert.DeserializeObject<ManagedIdentityTokenResponse>(tokenResponseString);
            
            return tokenResponseObject.AccessToken;
        };
    }
}


Read more here: https://stackoverflow.com/questions/67398491/getting-error-while-creating-sas-token-for-azure-storage-blob-with-msi

Content Attribution

This content was originally published by Shimon Shrem at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: