【问题标题】:How to authenticate an azure storage api request using a storage account key in python?如何在 python 中使用存储帐户密钥对 azure storage api 请求进行身份验证?
【发布时间】:2020-11-09 21:35:12
【问题描述】:

我正在尝试使用以下 python 函数对 azure storage api 的获取请求进行身份验证,但是我收到以下错误:

<Response [403]>
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

我要发出的请求的 url 是:

'https://{账户名}.dfs.core.windows.net/{文件系统}?directory={directory}&recursive=False&resource=filesystem'

REST api 的文档: https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/list

有关如何使用帐户密钥进行身份验证的文档: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key

def get_shared_access_authorization(self, directory):
        directory = directory
        file_system_name = self.fileSystem
        storage_account_name = self.storageAccountName
        storage_account_key = self.accountKey
        request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

        string_params = {
            'verb': 'GET',
            'Content-Encoding': '',
            'Content-Language': '',
            'Content-Length': '',
            'Content-MD5': '',
            'Content-Type': '',
            'Date': '',
            'If-Modified-Since': '',
            'If-Match': '',
            'If-None-Match': '',
            'If-Unmodified-Since': '',
            'Range': '',
            'CanonicalizedHeaders': 'x-ms-date:' + request_time + '\nx-ms-version:' + '2018-11-09' + '\n',
            'CanonicalizedResource': '/' + storage_account_name + '/' + file_system_name  + '\ndirectory:'+directory+'\nrecursive:false\nresource:filesystem'
        }

        string_to_sign = (string_params['verb'] + '\n'
                          + string_params['Content-Encoding'] + '\n'
                          + string_params['Content-Language'] + '\n'
                          + string_params['Content-Length'] + '\n'
                          + string_params['Content-MD5'] + '\n'
                          + string_params['Content-Type'] + '\n'
                          + string_params['Date'] + '\n'
                          + string_params['If-Modified-Since'] + '\n'
                          + string_params['If-Match'] + '\n'
                          + string_params['If-None-Match'] + '\n'
                          + string_params['If-Unmodified-Since'] + '\n'
                          + string_params['Range'] + '\n'
                          + string_params['CanonicalizedHeaders']
                          + string_params['CanonicalizedResource'])

        signed_string = base64.b64encode(
            hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'),
                     digestmod=hashlib.sha256).digest()).decode()

        headers = {
            'x-ms-date': request_time,
            'x-ms-version': '2018-11-09',
            'Authorization': ('SharedKeyLite ' + storage_account_name + ':' + signed_string)
        }

        return headers

我已检查所有输入(目录、文件系统名称、存储帐户名称和帐户密钥)是否正确。任何帮助将不胜感激。

更新:我尝试在 auth 标头中同时使用“SharedKey”和“SharedKeyLite”。

更新 2:通过将“假”换成“假”解决了问题。我已经概括了工作功能并将其包含在下面。

def get_shared_access_authorization(self, directory, file_system_name, storage_account_name, storage_account_key):

        request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

        string_params = {
            'verb': 'GET',
            'Content-Encoding': '',
            'Content-Language': '',
            'Content-Length': '',
            'Content-MD5': '',
            'Content-Type': '',
            'Date': '',
            'If-Modified-Since': '',
            'If-Match': '',
            'If-None-Match': '',
            'If-Unmodified-Since': '',
            'Range': '',
            'CanonicalizedHeaders': 'x-ms-date:' + request_time + '\nx-ms-version:' + '2018-11-09' + '\n',
            'CanonicalizedResource': '/' + storage_account_name + '/' + file_system_name  + '\ndirectory:'+directory+'\nrecursive:False\nresource:filesystem'
        }

        string_to_sign = (string_params['verb'] + '\n'
                          + string_params['Content-Encoding'] + '\n'
                          + string_params['Content-Language'] + '\n'
                          + string_params['Content-Length'] + '\n'
                          + string_params['Content-MD5'] + '\n'
                          + string_params['Content-Type'] + '\n'
                          + string_params['Date'] + '\n'
                          + string_params['If-Modified-Since'] + '\n'
                          + string_params['If-Match'] + '\n'
                          + string_params['If-None-Match'] + '\n'
                          + string_params['If-Unmodified-Since'] + '\n'
                          + string_params['Range'] + '\n'
                          + string_params['CanonicalizedHeaders']
                          + string_params['CanonicalizedResource'])

        signed_string = base64.b64encode(
            hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'),
                     digestmod=hashlib.sha256).digest()).decode()

        headers = {
            'x-ms-date': request_time,
            'x-ms-version': '2018-11-09',
            'Authorization': ('SharedKey ' + storage_account_name + ':' + signed_string)
        }

        return headers

【问题讨论】:

    标签: python azure authentication request


    【解决方案1】:

    请尝试将SharedKeyLite 更改为SharedKey 授权。从本质上更改以下代码行:

    'Authorization': ('SharedKeyLite ' + storage_account_name + ':' + signed_string)
    

    'Authorization': ('SharedKey ' + storage_account_name + ':' + signed_string)
    

    【讨论】:

    • 嗨 Guarav,我现在已经尝试过了,但仍然得到完全相同的错误。我现在将更新问题以反映这一点。
    • 您可以尝试的另一件事是将recursive=False 更改为recursive=false?
    • 嗨 Gaurav,这似乎已经解决了,非常感谢!我将使用有效的解决方案更新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 2017-06-07
    • 2020-04-11
    • 2016-01-31
    • 2019-05-23
    • 2014-03-31
    相关资源
    最近更新 更多