Получение ошибки 403 при создании общего ключа BLOB-объекта Azure

Я хотел создать контейнер больших двоичных объектов Azure, используя код Python, используя авторизацию общего ключа,

Я получаю ошибку ниже:

b'\xef\xbb\xbf<?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.\nRequestId:9e524b5e-301e-0051-4aa4-45750000\nTime:2023-02-21T03:27:02.8384023Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request \'xxxxxxxxxxxxxxxx\' is not the same as any computed signature. Server used following string to sign: \'PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Tue, 21 Feb 2023 03:27:01 GMT\nx-ms-version:2020-04-08\n/blobmediapedevwus2/mycontainer\nrestype:container\'.</AuthenticationErrorDetail></Error>'

Как это исправить?

Ниже приведен код Python:

import requests
import datetime
import hmac
import hashlib
import base64

# Set the storage account name and access key
STORAGE_ACCOUNT_NAME = 'vidyaflowerapp01'
STORAGE_ACCOUNT_KEY = "xxxxxxxxxx"

# Set the container name
CONTAINER_NAME = 'test'

# Set the request method and version
REQUEST_METHOD = 'PUT'
REQUEST_VERSION = '2020-04-08'

# Set the request date
REQUEST_DATE = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

CANONICALIZED_HEADERS = f'x-ms-date:{REQUEST_DATE}\nx-ms-version:{REQUEST_VERSION}\n'


# Set the canonicalized resource string
CANONICALIZED_RESOURCE = f'/{STORAGE_ACCOUNT_NAME}/{CONTAINER_NAME}\nrestype:container'

VERB = 'PUT'
Content_Encoding = ''
Content_Language = ''
Content_Length = ''
Content_MD5 = ''
Content_Type = ''
Date = ''
If_Modified_Since = ''
If_Match = ''
If_None_Match = ''
If_Unmodified_Since = ''
Range = ''
CanonicalizedHeaders = CANONICALIZED_HEADERS
CanonicalizedResource = CANONICALIZED_RESOURCE

STRING_TO_SIGN = (VERB + '\n' + Content_Encoding + '\n' + Content_Language + '\n' +
                Content_Length + '\n' + Content_MD5 + '\n' + Content_Type + 
                Date + '\n' + If_Modified_Since + '\n' + If_Match + '\n' +
                If_None_Match + '\n' + If_Unmodified_Since + '\n' + Range + '\n' +
                CanonicalizedHeaders + CanonicalizedResource)
signature = base64.b64encode(hmac.new(base64.b64decode(STORAGE_ACCOUNT_KEY), msg=STRING_TO_SIGN.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

# Generate the authorization header
auth_header = f'SharedKey {STORAGE_ACCOUNT_NAME}:{signature}'


# Set the request URL
request_url = f'https://{STORAGE_ACCOUNT_NAME}.blob.core.windows.net/{CONTAINER_NAME}?restype=container'

# Set the request headers
request_headers = {
    'x-ms-date': REQUEST_DATE,
    'x-ms-version': REQUEST_VERSION,
    'Authorization': auth_header
}

# Send the request
response = requests.put(request_url, headers=request_headers)
print(response.content)
print(response.status_code)

приведенный выше код использует авторизацию общего ключа для выполнения запроса, мы должны заменить ключ доступа и учетную запись хранения для проверки порядка

Текущий ответ: 403 Ожидаемый ответ: 201

Есть ли причина, по которой вы не используете Storage SDK для Python?

Gaurav Mantri 21.02.2023 05:41

@GauravMantri, да, наш поставщик хранилища использует авторизацию с общим ключом, которую мы устанавливаем для кеша nginx, однако они получают ответ 409, поэтому я хотел пока изолировать nginx, сделать прямой вызов хранилища и попробовать аналогичные команды, которые использует наш поставщик хранилища.

sagar 21.02.2023 05:44

Спасибо. Вы пытаетесь создать контейнер больших двоичных объектов в своем коде, верно?

Gaurav Mantri 21.02.2023 05:50

@GauravMantri да создание контейнера

sagar 21.02.2023 06:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я полагаю, что причина, по которой вы получаете эту ошибку, заключается в том, что вы устанавливаете значение Content-Length на 0 в STRING_TO_SIGN, однако сервер использует пустую строку при проверке подписи (пожалуйста, просмотрите сведения об ошибке, в которых указана строка для подписи, используемая сервером для проверить подпись).

Из этой ссылки:

Пожалуйста, попробуйте установить переменную Content_Length в пустую строку вместо 0.

Ответ принят как подходящий

В дополнение к тому, что сказал @Gaurav Mantri, вы получаете это из-за того, что заголовки авторизации сформированы неправильно. После воспроизведения с моей стороны это работало нормально, когда я заменял Date и Content Length пустой строкой при построении подписи. Ниже приведен полный код, который работал у меня.

import requests
import datetime
import hmac
import hashlib
import base64

# Set the storage account name and access key
STORAGE_ACCOUNT_NAME = '<XXX>'
STORAGE_ACCOUNT_KEY = "<XXX>"

# Set the container name
CONTAINER_NAME = 'mycontainer522'

# Set the request method and version
REQUEST_METHOD = 'PUT'
REQUEST_VERSION = '2020-04-08'

# Set the request date
REQUEST_DATE = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

CANONICALIZED_HEADERS = f'x-ms-date:{REQUEST_DATE}\nx-ms-version:{REQUEST_VERSION}\n'


# Set the canonicalized resource string
CANONICALIZED_RESOURCE = f'/{STORAGE_ACCOUNT_NAME}/{CONTAINER_NAME}\nrestype:container'

VERB = 'PUT'
Content_Encoding = ''
Content_Language = ''
Content_Length = ''
Content_MD5 = ''
Content_Type = ''
Date = ''
If_Modified_Since = ''
If_Match = ''
If_None_Match = ''
If_Unmodified_Since = ''
Range = ''
CanonicalizedHeaders = CANONICALIZED_HEADERS
CanonicalizedResource = CANONICALIZED_RESOURCE

STRING_TO_SIGN = (VERB + '\n' + Content_Encoding + '\n' + Content_Language + '\n' +
                Content_Length + '\n' + Content_MD5 + '\n' + Content_Type + '\n' +
                Date + '\n' + If_Modified_Since + '\n' + If_Match + '\n' +
                If_None_Match + '\n' + If_Unmodified_Since + '\n' + Range + '\n' +
                CanonicalizedHeaders + CanonicalizedResource)

# Generate the signature
signature = base64.b64encode(hmac.new(base64.b64decode(STORAGE_ACCOUNT_KEY), msg=STRING_TO_SIGN.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

# Generate the authorization header
auth_header = f'SharedKey {STORAGE_ACCOUNT_NAME}:{signature}'


# Set the request URL
request_url = f'https://{STORAGE_ACCOUNT_NAME}.blob.core.windows.net/{CONTAINER_NAME}?restype=container'

# Set the request headers
request_headers = {
    'x-ms-date': REQUEST_DATE,
    'x-ms-version': REQUEST_VERSION,
    'Authorization': auth_header
}

# Send the request
response = requests.put(request_url, headers=request_headers)
print(response.content)
print(response.status_code)

Полученные результаты:

форматирование вашего кода может быть проблемой, это полностью вставленный ответ кода

sagar 21.02.2023 08:57

@sagar, вы инициализировали дату переменной как Date = REQUEST_DATE. И при создании string_to_sign это вызывает проблему. Я использовал Date='' и получил желаемые результаты. Вы можете использовать приведенный выше код, в котором я заменил дату и длину содержимого пустой строкой, чтобы успешно создать контейнер.

SwethaKandikonda 21.02.2023 10:13

@swathi, не уверен, что я все еще получаю ту же ошибку, обновленный код, какая-либо ошибка конфигурации, например, запрет на использование общего ключа в моем хранилище?

sagar 21.02.2023 10:47

@sagar Это из-за версии запроса, которую вы упомянули в своем коде. Решение относится к первому обновлению, о котором вы упомянули, то есть REQUEST_VERSION = '2020-04-08'. Глядя на ваше недавнее редактирование, я вижу, что вы изменили его на «2014-02-14». Попробуйте изменить версию на 2020-04-08 или, если вы пытаетесь использовать «2014-02-14», посмотрите документ, предоставленный @Gaurav Mantri, и соответствующим образом сформируйте String_to_sign.

SwethaKandikonda 21.02.2023 11:14

@swathi, я изменил версию на тот же результат

sagar 21.02.2023 11:18

@sagar, я обновил код, теперь попробуйте скопировать и вставить тот же код, заменив его своим контейнером и ключом доступа.

SwethaKandikonda 21.02.2023 11:27

Давайте продолжим обсуждение в чате.

SwethaKandikonda 21.02.2023 11:31

это работает для другой учетной записи, однако теперь я получаю другую ошибку для существующей, но я должен принять этот ответ python3 test.py b'\xef\xbb\xbf<?xml version = "1.0" encoding = "utf-8"? ><Error><Code>AuthorizationFailure</Code><M‌​essage>Этот запрос не авторизован для выполнения этой операции.\nRequestId:77440ab1-e01e-000f-7ce0-459e3e000000\n‌​Time:2023-02-21T10: 3‌​5:09.1160088Z</Messa‌​ge></Error>' 403

sagar 21.02.2023 11:36

@sagar, судя по вашему сообщению об ошибке This request is not authorized to perform this operation, у вас может не хватить прав для создания контейнера в целевой учетной записи хранения.

SwethaKandikonda 21.02.2023 11:39

@swathi, для включения всей сети в разделе сети, это сработало, большое спасибо за вашу помощь.

sagar 21.02.2023 11:46

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