Here's my code to find Storage Containers:
var api = $"https://{storageAccountName}.blob.core.windows.net/?comp=list";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken); //token obtained from https://storage.azure.com/
client.BaseAddress = new Uri($"https://{storageAccountName}.blob.core.windows.net/");
using (var responseGet = client.GetAsync(api).Result)
{
if (responseGet.IsSuccessStatusCode)
{
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(responseGet.Content.ReadAsStringAsync().Result);
foreach (XmlNode a in xmlDocument.DocumentElement.SelectNodes("Containers/Container"))
{
containerNameList.Add(a.SelectSingleNode("Name").FirstChild.Value);
}
}
}
}
I got an error:
`StatusCode: 403, ReasonPhrase: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.', Version: 1.1, Content:
System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
Server: Windows-Azure-Blob/1.0
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: 9d70d7ff-901e-0096-4c5b-aec38d000000
Date: Mon, 09 Dec 2019 06:38:16 GMT
Content-Length: 438
Content-Type: application/xml
}`
I obtained the access token from https://storage.azure.com/
And here's the code to remove the storage container:
var strApi = $"https://{storageAccountName}.blob.core.windows.net/{storageContainerName}?restype=container";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
client.BaseAddress = new Uri(BaseManagementUri);
using (var responseGet = client.DeleteAsync(strApi).Result)
{
if (responseGet.IsSuccessStatusCode)
{
log.LogInformation($"Deleted {storageAccountName}");
}
else
{
log.LogWarning($"Failed to deleted {storageAccountName}\n{responseGet.Content.ReadAsByteArrayAsync().Result}");
}
}
}
How to obtain the proper access token and what all headers required for the above operations ?
According to my research, we can use Azure Active Directory (AD) to authorize requests to Blob storage. For more details, please refer to the document
The detailed steps are as below.
Storage Blob Data Contributor
role to the sp. You can refer to the article to know more details about how to do it. az ad sp create-for-rbac --name "" --scope <"/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"> --role "Storage Blob Data Contributor"
URL : https://login.microsoftonline.com/{tenant}/v2.0/token
Method : POST
Headers : Content-Type: application/x-www-form-urlencoded
Body :
"grant_type" : "client_credentials"
"scope" : "https://storage.azure.com/.default"
"client_id" : "<your sp app id>"
"client_secret" : "<your sp password>"
URL: https://myaccount.blob.core.windows.net/?comp=list
Method: Get
Headers:
x-ms-version : 2019-02-02
Authorization: Bearer <access token>
URL: https://myaccount.blob.core.windows.net/mycontainer?restype=container
Method : DELETE
Headers:
x-ms-version : 2019-02-02
Authorization: Bearer <access token>
Besides, if you want to do that with Azure MSI, please refer to the blog
Update
Regarding how to call Azure storage rest api with MSI in Azure function, please refer to the following steps. 1. Adding a system-assigned identity
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Xml.Linq;
using Microsoft.Azure.Services.AppAuthentication;
using RestSharp;
using System.Text;
namespace TestFunV2
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var tokenProvider = new AzureServiceTokenProvider();
var accesstoken = await tokenProvider.GetAccessTokenAsync("https://storage.azure.com/");
var client = new RestClient("https://hurystorage.blob.core.windows.net/?comp=list");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + accesstoken);
request.AddHeader("x-ms-version", "2019-02-02");
IRestResponse response = await client.ExecuteTaskAsync(request);
if (response.IsSuccessful) {
var xmlstring = response.Content;
string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xmlstring.StartsWith(_byteOrderMarkUtf8))
{
xmlstring = xmlstring.Remove(0, _byteOrderMarkUtf8.Length);
}
XElement x = XElement.Parse(xmlstring);
foreach (XElement container in x.Element("Containers").Elements("Container"))
{
log.LogInformation("Container name = {0}", container.Element("Name").Value);
}
return (ActionResult)new OkObjectResult("ok");
}
return new BadRequestObjectResult("failure");
}
}
}