rest - 如何在 C# 中使用 SAS 访问 Azure blob

标签 rest azure blob

当我尝试使用临时共享访问签名 (SAS) 创建/访问 Azure blob 时,我收到“远程服务器返回错误:(403) 禁止”。错误。有人可以帮我确定这段代码出了什么问题吗?

    // Calling this function from Main().
    public void uploadToBlob()
    {
        string content = "Hello World - Content of the file";
        string fileName = "TestFile";
        UploadFileToAzureBlobStorage(content, fileName);
    }

    void UploadFileToAzureBlobStorage(string content, string fileName)
    {
        string storageKey = "SAS Key";
        string storageAccount = "Storage Account name";
        string containerName = "Container Name";
        string blobName = fileName;

        string method = "PUT";
        string sampleContent = content;
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

        string requestUri = $"https://{storageAccount}.blob.core.windows.net/{containerName}/{blobName}";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
        string now = DateTime.UtcNow.ToString("R");
        request.Method = method;
        request.ContentType = "text/plain; charset=UTF-8";
        request.ContentLength = contentLength;
        request.Headers.Add("x-ms-version", "2015-12-11");
        request.Headers.Add("x-ms-date", now);
        request.Headers.Add("x-ms-blob-type", "BlockBlob");
        request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, containerName, blobName));

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }

        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
            if (resp.StatusCode == HttpStatusCode.OK)
            { }
        }
    }

    public string AuthorizationHeader(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName, string blobName)
    {
        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:{now}\nx-ms-version:2015-12-11";
        string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
        string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{headerResource}\n{urlResource}";
        HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(storageKey));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
        String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
        return AuthorizationHeader;
    }

最佳答案

当您使用帐户 key 时,需要您在上面使用的代码。这时您需要计算并在请求中包含 Authorization header 。如果您使用共享访问签名 (SAS) token ,则无需执行所有这些操作,因为 SAS token 已包含授权信息。

假设您的 SAS token 有效并且包含上传文件的适当权限,您的代码将变得非常简单。请参阅下面修改后的代码:

void UploadFileToAzureBlobStorage(string content, string fileName)
{
    string sasToken = "SAS Key";
    string storageAccount = "Storage Account name";
    string containerName = "Container Name";
    string blobName = fileName;

    string method = "PUT";
    string sampleContent = content;
    int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

    string requestUri = $"https://{storageAccount}.blob.core.windows.net/{containerName}/{blobName}?{sasToken}";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
    request.Method = method;
    request.ContentType = "text/plain; charset=UTF-8";
    request.ContentLength = contentLength;
    request.Headers.Add("x-ms-blob-type", "BlockBlob");

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
    }

    using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
    {
        if (resp.StatusCode == HttpStatusCode.OK)
        { }
    }
}

关于rest - 如何在 C# 中使用 SAS 访问 Azure blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46648958/

相关文章:

python - 属性错误 : 'str' object has no attribute 'items'

javascript - 使用带有 Node.js 的 REST api 服务器连接到我的 sql 数据库时出现问题

c# - Azure WebJob中的手动触发,末尾不输出到队列

mysql - 使用php导入mysql blob数据

ios - 试图将图像存储到 sqlite 中,当我尝试检索它时,它是一个字节而不是 200 万字节

javascript - Blob 图像从数据库到 Java 以及从 Java 到 Javascript 图像

ruby-on-rails - Rails 中默认 RESTFUL 路由的覆盖方法

android - 带有 gradle 的 android 的 xml spring

Azure函数无法连接到Azure SQL数据库

django - 如何将存储库中的特定 django 文件夹部署到 azure 应用程序服务?