Подпись MAC, найденная в HTTP-запросе ' ', отличается от любой вычисленной подписи. Сервер использовал следующую строку для подписи: 'PUT

Я пытаюсь создать общий доступ к файлам через REST API, но получаю эту ошибку

AuthenticationFailed Серверу не удалось аутентифицировать запрос. Убедитесь, что значение>>> Заголовок авторизации сформировано правильно, включая подпись. RequestId:aba10b5f-001a-0026-49cb-51d887000000 Время:2017-10-30T22:04:13.9907093Z Запись MAC >, найденная в HTTP-запросе> > > 'U8UvWw4KO0fXAk21p/fuXhfqpDdgK7OZn29r5JQ1, не совпадает с мнением>, что не совпадает с4. Сервер использовал следующую строку для подписи: 'PUT

Это мой код:

static void CreatFileShare()
    {
        string requestMethod = "PUT";
        string urlPath = strShareName + "?restype=share";
        string urlPathResource = "restype:share";

        String canonicalizedResource = String.Format("/{0}/{2}\n{1}", StorageAccountName, urlPathResource, /*strShareName*/ "MFS2");
        try
        {
            HttpWebRequest request = GetWebRequest(requestMethod, urlPath, canonicalizedResource, "CreateShare");
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                Console.WriteLine("Response status code: " + response.StatusCode + ".  Successfully Create the share \"" + strShareName + "\".");
            }
        }
        catch (WebException ex)
        {
            ThrowWebException(ex);
        }
    }

static HttpWebRequest GetWebRequest(string requestMethod, string urlPath, String canonicalizedResource, string MethodType)
    {
        HttpWebRequest request = null;
        try
        {
            const string type = "file";
            const string msVersion = "2017-04-17";
            String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
            String canonicalizedHeaders = "";

            //canonicalizedHeaders = String.Format("x-ms-date:{0}\nx-ms-version:{1}", dateInRfc1123Format, msVersion);
            canonicalizedHeaders = String.Format("x-ms-date:{0}\nx-ms-version:{1}\n", dateInRfc1123Format, msVersion);
            if (MethodType == "CreateFile")
            {
                canonicalizedHeaders = String.Format("x-ms-content-length:1024\nx-ms-date:{0}\nx-ms-type:file\nx-ms-version:{1}", dateInRfc1123Format, msVersion);
            }

            String stringToSign = "";


            //stringToSign = String.Format("{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}", requestMethod, canonicalizedHeaders, canonicalizedResource);
            stringToSign = String.Format("{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}{2}", requestMethod, canonicalizedHeaders, canonicalizedResource);

            String authorizationHeader = CreateAuthorizationHeader(stringToSign);

            Uri uri = new Uri(FileEndPoint + urlPath);
            request = (HttpWebRequest)WebRequest.Create(uri);
            if (requestMethod != "Get")
            {
                request.ContentLength = 0;
            }

            request.Method = requestMethod;
            request.Headers.Add("x-ms-date", dateInRfc1123Format);
            request.Headers.Add("x-ms-version", msVersion);
            request.Headers.Add("Authorization", authorizationHeader);
            request.Headers.Add("Accept-Charset", "UTF-8");
            request.Accept = "application/atom+xml,application/xml";
            if (MethodType == "CreateFile")
            {
                request.Headers.Add("x-ms-content-length", "1024");
                request.Headers.Add("x-ms-type", type);

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }

        return request;
    }

Я использую алгоритм HMAC-SHA256 в CreateAuthorizationHeader метод

Мое приложение также имеет логику для получения общих файловых ресурсов и каталогов / файлов в учетной записи хранения, и это работает нормально. Проблема возникает в тот момент, когда я хочу создать файл, общий ресурс или общий снимок.

Любая помощь будет принята с благодарностью!

1 ответ

Решение

Для Create Share запрос будет:

PUT https://{your-storage-accountname}.file.core.windows.net/{share-name}?restype=share

Request Headers:  
x-ms-version: 2017-04-17 
x-ms-date: <date>  
Authorization: SharedKey {your-storage-accountname}:{shared-key-signature-string}  

Канонизированная строка заголовков будет:

x-ms-date:Wed, 01 Nov 2017 05:53:50 GMT\nx-ms-version:2017-04-17\n

Строка Canonicalized Resource будет выглядеть так:

/{your-account-name}/{your-share-name}\nrestype:share

В то время как для создания файла запрос будет:

PUT https://{your-storage-accountname}.file.core.windows.net/{share-name}/{file}

Request Headers:  
x-ms-version: 2017-04-17 
x-ms-date: <date>  
x-ms-content-length: 1024 //This header specifies the maximum size for the file, up to 1 TB.
Authorization: SharedKey {your-storage-accountname}:{shared-key-signature-string}  

Канонизированная строка заголовков будет:

x-ms-content-length:1024\nx-ms-date:Wed, 01 Nov 2017 06:03:57 GMT\nx-ms-type:file\nx-ms-version:2017-04-17\n

Строка Canonicalized Resource будет выглядеть так:

/{your-account-name}/{your-share-name}/{your-file}
//e.g. /brucchstorage/myshare1/helloworld.txt

Для вашего кода вам нужно изменить параметры urlPath а также canonicalizedResource под вашим CreatFileShare метод для поддержки создания файла. Также вам нужно добавить символ новой строки (\n) к canonicalizedHeaders параметр под вашим GetWebRequest Метод для MethodType равен CreateFile,

Кроме того, общая причина этой проблемы связана с генерацией для CanonicalizedResource и CanonicalizedHeaders. Я бы рекомендовал обратиться к разделу Аутентификация для служб хранилища Azure, чтобы лучше их понять. Кроме того, вы можете использовать fiddler для захвата сетевых трассировок и сравнения строки для подписи из ответа об ошибке с вашим локальным значением, чтобы сузить эту проблему.

Как отметил Гаурав Мантри, вы можете использовать клиентскую библиотеку хранилища Azure для.NET, чтобы достичь своей цели простым способом. Более подробную информацию вы можете найти здесь.

Другие вопросы по тегам