Azure REST API 创建容器,.NET 客户端配置文件,403 禁止,找到的 MAC 签名与任何计算的签名不同

2024-01-19

在阅读了所有与此接近的帖子后,我仍然找不到解决方案,并且在“摆弄”了几个小时之后,这里有一篇帖子,希望有人有一个想法:

我发现的最接近的回应是here https://stackoverflow.com/questions/4612693/getting-403-forbidden-webexception-for-azure-blob-put-request

但这些帖子中的两件事并不适用: 1. 我使用的示例代码在大多数情况下肯定有效。 2. 我无权访问任何 Azure StorageClient 简化程序,因为我需要使用 .NET 客户端配置文件。 3. 这可能是一个我没有看到的愚蠢错误:-)

这是电话:

// Create Blob
// using REST: http://msdn.microsoft.com/en-us/library/windowsazure/dd135733.aspx
BlobHelper blobHelper = new BlobHelper(_storageAccountName, _storageKey);
Console.WriteLine("Create container...");
if (!blobHelper.CreateContainer("mytestcontainer")) //(blobInfo.ContainerName))
   {
     Console.WriteLine("REST: Create Blob Failed");
   }

这是电汇请求(fiddler):

PUT /devstoreaccount1/mytestcontainer?restype=container HTTP/1.1
x-ms-date: Mon, 25 Jun 2012 16:54:01 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey devstoreaccount1:REpHdtTSQrwGtXuEbLJmRQdpe/j2l5icmGUeFkQ09jw=
Host: 127.0.0.1:10000
Content-Length: 0
Connection: Keep-Alive

无论我使用实时 Azure 存储还是开发人员存储,都会发生同样的情况。

这是电报响应:

HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Content-Length: 698
Content-Type: application/xml
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: d5430ddc-f146-4102-b8db-a8bfab0ed82f
Date: Mon, 25 Jun 2012 16:54:00 GMT

<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:d5430ddc-f146-4102-b8db-a8bfab0ed82f
Time:2012-06-25T16:54:01.3354093Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'REpHdtTSQrwGtXuEbLJmRQdpe/j2l5icmGUeFkQ09jw=' is not the same as any computed signature. Server used following string to sign: 'PUT


0








x-ms-date:Mon, 25 Jun 2012 16:54:01 GMT
x-ms-version:2009-09-19
/devstoreaccount1/devstoreaccount1/mytestcontainer
restype:container'.</AuthenticationErrorDetail></Error>

不用说,这让我发疯,所以任何建议都很感激。

源代码,直接来自Azure存储REST API 示例 http://azurestoragesamples.codeplex.com/releases/view/61325,RESTHelper.cs。这适用于许多场景,但不适用于以下场景:

    #region REST HTTP Request Helper Methods

    // Construct and issue a REST request and return the response.

    public HttpWebRequest CreateRESTRequest(string method, string resource, string requestBody = null, SortedList<string, string> headers = null, 
        string ifMatch = "", string md5 = "")
    {
        byte[] byteArray = null;
        DateTime now = DateTime.UtcNow;
        string uri = Endpoint + resource;

        HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
        request.Method = method;
        request.ContentLength = 0;
        request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
        request.Headers.Add("x-ms-version", "2009-09-19"); //2009-09-19, 2011-08-18

        if (IsTableStorage)
        {
            request.ContentType = "application/atom+xml";

            request.Headers.Add("DataServiceVersion", "1.0;NetFx");
            request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
        }

        if (headers != null)
        {
            foreach (KeyValuePair<string, string> header in headers)
            {
                request.Headers.Add(header.Key, header.Value);
            }
        }

        if (!String.IsNullOrEmpty(requestBody))
        {
            request.Headers.Add("Accept-Charset", "UTF-8");

            byteArray = Encoding.UTF8.GetBytes(requestBody);
            request.ContentLength = byteArray.Length;
        }

        request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, ifMatch, md5));

        if (!String.IsNullOrEmpty(requestBody))
        {
            request.GetRequestStream().Write(byteArray, 0, byteArray.Length);
        }

        return request;
    }


    // Generate an authorization header.
    //RHT: http://msdn.microsoft.com/en-us/library/dd179428.aspx

    public string AuthorizationHeader(string method, DateTime now, HttpWebRequest request, string ifMatch = "", string md5 = "")
    {
        string MessageSignature;

        if (IsTableStorage)
        {
            MessageSignature = String.Format("{0}\n\n{1}\n{2}\n{3}",
                method,
                "application/atom+xml",
                now.ToString("R", System.Globalization.CultureInfo.InvariantCulture),
                GetCanonicalizedResource(request.RequestUri, StorageAccount)
                );
        }
        else
        {
            MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
                method,
                (method == "GET" || method == "HEAD") ? String.Empty : request.ContentLength.ToString(),
                ifMatch,
                GetCanonicalizedHeaders(request),
                GetCanonicalizedResource(request.RequestUri, StorageAccount),
                md5
                );
        }
        byte[] SignatureBytes = System.Text.Encoding.UTF8.GetBytes(MessageSignature);
        System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(StorageKey));
        String AuthorizationHeader = "SharedKey " + StorageAccount + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
        return AuthorizationHeader;
    }

    // Get canonicalized headers.

    public string GetCanonicalizedHeaders(HttpWebRequest request)
    {
        ArrayList headerNameList = new ArrayList();
        StringBuilder sb = new StringBuilder();
        foreach (string headerName in request.Headers.Keys)
        {
            if (headerName.ToLowerInvariant().StartsWith("x-ms-", StringComparison.Ordinal))
            {
                headerNameList.Add(headerName.ToLowerInvariant());
            }
        }
        headerNameList.Sort();
        foreach (string headerName in headerNameList)
        {
            StringBuilder builder = new StringBuilder(headerName);
            string separator = ":";
            foreach (string headerValue in GetHeaderValues(request.Headers, headerName))
            {
                string trimmedValue = headerValue.Replace("\r\n", String.Empty);
                builder.Append(separator);
                builder.Append(trimmedValue);
                separator = ",";
            }
            sb.Append(builder.ToString());
            sb.Append("\n");
        }
        return sb.ToString();
    }

    // Get header values.

    public ArrayList GetHeaderValues(NameValueCollection headers, string headerName)
    {
        ArrayList list = new ArrayList();
        string[] values = headers.GetValues(headerName);
        if (values != null)
        {
            foreach (string str in values)
            {
                list.Add(str.TrimStart(null));
            }
        }
        return list;
    }

    // Get canonicalized resource.

    public string GetCanonicalizedResource(Uri address, string accountName)
    {
        StringBuilder str = new StringBuilder();
        StringBuilder builder = new StringBuilder("/");
        builder.Append(accountName);
        builder.Append(address.AbsolutePath);
        str.Append(builder.ToString());
        NameValueCollection values2 = new NameValueCollection();
        if (!IsTableStorage)
        {
            //Uri.EscapeDataString(...)
            //WebUtility.HtmlEncode(...)     
            //https://stackoverflow.com/questions/36315/alternative-to-httputility-for-net-3-5-sp1-client-framework
            //NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
            //foreach (string str2 in values.Keys)
            //{
            //    ArrayList list = new ArrayList(values.GetValues(str2));
            //    list.Sort();
            //    StringBuilder builder2 = new StringBuilder();
            //    foreach (object obj2 in list)
            //    {
            //        if (builder2.Length > 0)
            //        {
            //            builder2.Append(",");
            //        }
            //        builder2.Append(obj2.ToString());
            //    }
            //    values2.Add((str2 == null) ? str2 : str2.ToLowerInvariant(), builder2.ToString());
            //}
        }
        ArrayList list2 = new ArrayList(values2.AllKeys);
        list2.Sort();
        foreach (string str3 in list2)
        {
            StringBuilder builder3 = new StringBuilder(string.Empty);
            builder3.Append(str3);
            builder3.Append(":");
            builder3.Append(values2[str3]);
            str.Append("\n");
            str.Append(builder3.ToString());
        }
        return str.ToString();
    }

    #endregion

谢谢斯玛克斯,

确实,让我大开眼界,它让我找到了解决方案:

.NET Client Profile 缺少 HttpUtility,因此我将其替换为不提供构建器所需格式的正则表达式。所以,我用这个替换了它:

http://google-gdata.googlecode.com/svn/trunk/clients/cs/src/core/HttpUtility.cs http://google-gdata.googlecode.com/svn/trunk/clients/cs/src/core/HttpUtility.cs

它有效。这是标题现在的样子:

PUT /devstoreaccount1/mytestcontainer?restype=container HTTP/1.1
x-ms-date: Mon, 25 Jun 2012 18:57:04 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey devstoreaccount1:J5D1E7PK/yNBgQITHmYgVuu4cHtcGad+YKGb1Lh/YUU=
Host: 127.0.0.1:10000
Content-Length: 0

结果:

HTTP/1.1 201 Created
Transfer-Encoding: chunked
Last-Modified: Mon, 25 Jun 2012 18:57:04 GMT
ETag: 0x8CF211B72040930
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 079bcdc1-a7fa-4207-99cd-b7f1c2d1b981
x-ms-version: 2009-09-19
Date: Mon, 25 Jun 2012 18:57:04 GMT

0

我已经单步执行了代码,但没有看到这种差异,再次感谢, R。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Azure REST API 创建容器,.NET 客户端配置文件,403 禁止,找到的 MAC 签名与任何计算的签名不同 的相关文章

  • 使用 Azure 机器学习检测图像中的符号

    4年前我发帖这个问题 https stackoverflow com q 6999920 411094不幸的是 得到的一些答案超出了我的技能水平 我刚刚参加了一次构建巡演会议 他们在会上谈论了机器学习 这让我想到了使用 ML 来解决我的问题
  • k8s CronJob 在 pod 列表上循环

    我想在特定命名空间中的 pod 上运行循环 但诀窍是在 cronJob 中执行此操作 是否可以内联 kubectl get pods n foo 这里的技巧是在你获得 Pod 列表后 我需要循环并在 15 秒的超时时间内将每个 Pod 删除
  • Azure 忽略 ARM 模板中的站点配置设置

    我正在尝试开发用于部署多个 Web 应用程序的 ARM 模板 但我在尝试使用 Microsoft Web sites config 中提供的设置来配置 Web 应用程序时遇到困难 无论我在那里输入什么 当我部署 web 应用程序时 这些设置
  • 如何通过ARM模板输出返回Redis的primaryKey?

    我正在尝试借助下面列出的 ARM 模板来部署 Redis 然后返回其主密钥 Azure 门户中 Redis 的 访问密钥 gt 主 下可用的秘密字符串 但是 我从管道 AzureResourceManagerTemplateDeployme
  • 查找“未找到身份”的角色分配的可靠方法是什么?在 Azure 上使用 Powershell?

    如果您在 Azure 中分配角色 然后在删除角色分配之前删除该身份 则会出现 找不到身份 的情况 健康 状况 它是无害的 但它会占用角色分配空位并使角色分配列表变得混乱 我想找到并删除这些 我想这个 Get AzRoleAssignment
  • 如何在 FineUploader Azure 请求中包含 Content-MD5 标头?

    我想使用 Content MD5 标头向 Azure 提供客户端生成的上传文件的 MD5 哈希值 我如何在 FineUploader 中完成此任务 目标受众 Firefox Chrome Safari Opera 和 IE10 判断依据这个
  • Azure Function App Azure 服务总线触发器触发两次

    我使用带有服务总线触发器的 Azure Function Apps 来读取服务总线并对服务总线消息的内容执行操作 服务总线接收 JSON 序列化对象 然后将 JSON 消息反序列化回 Function App 中的对象 然而 由于某种原因
  • Windows Azure 虚拟机配备什么类型的显卡?

    我正在考虑在 Windows Azure 虚拟机上运行一些图形密集型程序 但不确定它们有什么样的硬件 所有虚拟机都具有相同的 GPU 吗 您对此有何体验 Azure 虚拟机中的 GPU 可能非常基本 并且很可能不具备执行密集图形操作所需的处
  • 如何从 Azure Key Vault KeyBundle 创建 X509Certificate2 对象

    我正在使用 Azure Key Vault 来保护我们的密钥和机密 但我不确定如何使用通过 net SDK 检索到的 KeyBundle 如何创建 X509Certificate2 对象 当您在 KeyVault 中导入 创建证书时 会创建
  • 更改 Azure 备份保管库冗余

    我们使用 Azure 备份并将备份保管库设置为使用 GRS 我们想使用 LRS 来代替 据了解 一旦机器添加到保险库中 这一点就无法更改 我们需要从头开始 两个问题 在为同一服务器设置新保管库之前 是否需要先删除当前保管库 当前的备份可以转
  • Azure“IIS 应用程序初始化预加载”记录“不支持该请求”异常

    在运行 WebApi 2 Web 应用程序的 Azure Web 应用程序中 每次将应用程序从 Preprod 交换到 Production 插槽时 我的日志中都会出现此错误 System Web HttpException 0x80004
  • 通过 Azure Active Directory 进行 FreeRADIUS 身份验证

    我刚刚配置了 FreeRadius 但我想对 Azure AD 中的用户进行身份验证 我知道可以将 FreeRADIUS 与 Active Directory 链接 但我找不到有关 Azure AD 的任何信息 有谁知道是否可能 一个可能的
  • 使用 SqlBulkCopy 和 Azure 并行批量插入

    我在云上有一个带有 sql azure 数据库的 azure 应用程序 我有一个辅助角色 需要对文件 最多约 3000 万行 进行解析 处理 因此我无法直接使用 BCP 或 SSIS 我目前正在使用 SqlBulkCopy 但这似乎太慢了
  • 如何在 SPA 应用程序中从 Web API 访问 Graph API

    我有一个与 WebAPI 通信的 Angular 应用程序 并且用户根据 Azure Active Directory 进行身份验证 我按照这里的示例进行操作https github com Azure Samples active dir
  • 使用 azure 队列的 nservicebus 本地主机

    似乎所有附带的示例项目服务总线发送者和主机是 Web 角色和辅助角色 并通过角色入口点托管 的设置 我需要做这样的事情 Web 角色发送消息 gt 本地主机处理消息 是否可以将本地主机配置为仅使用 Azure 队列存储 而不是 MSMQ 我
  • 来自 IOS Xcode 的 Azure 推送通知错误

    我觉得我是世界上第一个尝试让 iOS 快速与 Azure 配合使用的人 但没有太多帮助 我跟着这个创建 iOS 应用程序 https azure microsoft com en us documentation articles app
  • DocumentDb GUID 索引精度

    假设我们的文档中有一个非唯一的 GUID UUID 值 id 123456 Key 117dfd49 a71d 413b a9b1 841e88db06e8 Name Kaapstad 我们只想通过平等来查询这一点 不需要范围或 order
  • 通过graph api或graph sdk为整个B2C实例创建用户自定义属性

    我想通过 graph api 或 sdk 为整个 b2c 实例创建 用户自定义属性 就像我在 ms 之后通过 Azure Portal 所做的那样文档 https learn microsoft com pl pl azure active
  • 执行带有开始日期和结束日期的azure数据工厂foreach活动

    我有一个 json 文件 它包含开始日期和结束日期 我需要使用 azure 数据工厂 foreach 迭代此开始日期和结束日期 据我所知 foreach 期望项目 集合 数组 但就我而言 我只有两个项目 即开始日期和结束日期 我想运行数据工
  • 直接从浏览器将文件上传到 Azure Blob 存储?

    是否可以创建一个 html 表单以允许 Web 用户直接将文件上传到 azure blob 存储 而无需使用其他服务器作为中介 S3 和 GAW blobstore 都允许这样做 但我找不到任何对 azure blob 存储的支持 编辑 2

随机推荐