如何使用C#REST API查找和删除Azure存储容器?

问题描述 投票:0回答:1

这是我的代码,用于查找存储容器:

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);
            }
        }
    }
}

我有一个错误:

`StatusCode:403,ReasonPhrase:“服务器无法通过身份验证请求。确保形成了Authorization标头的值正确地包含签名。”,版本:1.1,内容:

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
}`

我从https://storage.azure.com/获得了访问令牌

这是删除存储容器的代码:

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}");
        }
    }
}

如何获得正确的访问令牌以及上述操作所需的所有标头是什么?

c# azure rest azure-storage azure-storage-blobs
1个回答
0
投票

根据我的研究,我们可以使用Azure Active Directory(AD)授权对Blob存储的请求。有关更多详细信息,请参阅document

详细步骤如下。

  1. 创建服务主体并将Storage Blob Data Contributor角色分配给sp。您可以参考article以了解更多有关如何操作的详细信息。
az ad sp create-for-rbac --name "" --scope <"/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"> --role "Storage Blob Data Contributor"
  1. Get Azure AD access token
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>"

enter image description here

  1. 调用Azure Blob rest api
    • 列出容器
URL: https://myaccount.blob.core.windows.net/?comp=list
Method: Get
Headers:
         x-ms-version : 2019-02-02
         Authorization: Bearer <access token>

enter image description here

  • 删除容器
URL: https://myaccount.blob.core.windows.net/mycontainer?restype=container  
Method : DELETE
Headers:
         x-ms-version : 2019-02-02
         Authorization: Bearer <access token>

enter image description here

此外,如果要使用Azure MSI进行此操作,请参考blog


更新

关于如何在Azure函数中使用MSI调用Azure存储休息api,请参考以下步骤。1. Adding a system-assigned identity

  1. 将存储Blob数据贡献者角色分配给MSIenter image description here

  2. 代码

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");


        }
    }
}

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.