使用 generate_blob_sas() 时为 blob 生成的 SAS URL 不正确?

问题描述

我正在尝试检索 Azure 美国政府帐户的存储帐户容器中 blob 的 URL。特别是,我试图通过此函数返回最近更新/上传的 blob 的 URL。但是,生成的 URL 末尾的 SAS 令牌不正确,我不知道为什么。这是我的代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from math import pow,floor,log,ceil

def leading_zeros(x):
    return len(bin(x).split('b')[-1].split('1')[-1])

def f(x):
    s = 0
    for c,i in enumerate(range(1,x)):
        a = pow(2,len(bin(i).split('b')[-1].split('1')[-1]))
        s += a
    return s

def g(x): return sum([pow(2,i)*floor((x+pow(2,i)-1)/pow(2,i+1)) for i in range(0,32)])

def h(x):
    s = 0
    extra = 0
    extra_s = 0
    for i in range(0,32):
        num = (x+pow(2,i)-1)
        den = pow(2,i+1)
        fraction = num/den
        floored = floor(num/den)
        power = pow(2,i)
        product = power*floored
        if product == 0:
            break
        s += product
        extra += (fraction - floored)
        extra_s += power*fraction
        #print(f"i={i} s={s} num={num} den={den} fraction={fraction} floored={floored} power={power} product={product} extra={extra} extra_s={extra_s}")
    return s

def z(x):
    upper_bound = floor(log(x,2)) if x > 0 else 0
    s = 0
    for i in range(upper_bound+1):
        num = (x - pow(2,i))
        den = pow(2,i+1)
        fraction = num/den
        floored = floor(fraction)
        added = pow(2,i)
        s += floored * added
        s += added
        print(f"i={i} s={s} upper_bound={upper_bound} num={num} den={den} floored={floored} added={added}")
    return s
#    return sum([floor((x - pow(2,i))/pow(2,i+1) + pow(2,i)) for i in range(floor(log(x,2)))])

def tower(x):
    table = [[" " for i in range(x)] for j in range(ceil(log(x,2)))]
    for i in range(1,x):
        p = leading_zeros(i)
        table[p][i] = 2**p
    for row in table:
        for col in row:
            print(col,end='')
        print()


# h(9000)
for i in range(1,16):
    tower(i)
    print((i,f(i),g(i),h(i),z(i-1)))

当我尝试使用给定的 import pytz import keys as key from datetime import datetime,timedelta from azure.storage.blob import BlobServiceClient,BlobSasPermissions,generate_blob_sas """ Access contents of the Azure blob storage. Retrieve the most recently uploaded block blob URL. @param blob_service_client: BlobServiceClient object @param container_name: string name of container (can change this parameter in the driver code) @return URL of the most recently uploaded blob to the storage container with the SAS token at the end @return name of the blob that was most recently updated/uploaded """ def retrieve_blob_from_storage(account_name,container_name): # Instantiate a BlobServiceClient using a connection string blob_service_client = BlobServiceClient.from_connection_string(key.CONNECTION_STRING_1) container_client = blob_service_client.get_container_client(container_name) # Get the most recently uploaded (modified) blob on the container Now = datetime.Now(pytz.utc) datetime_list = [] for blob in container_client.list_blobs(): datetime_list.append(blob.last_modified) youngest = max(dt for dt in datetime_list if dt < Now) blob_name = "" for blob in container_client.list_blobs(): if blob.last_modified == youngest: blob_name = blob.name # Generate SAS token to place at the end of the URL of the last uploaded (modified) blob on the container sas = generate_blob_sas(account_name = account_name,account_key = key.CONNECTION_STRING_1,container_name = container_name,blob_name = blob_name,permission = BlobSasPermissions(read = True),expiry = datetime.utcNow() + timedelta(hours = 2)) sas_url = 'https://' + account_name + '.blob.core.usgovcloudapi.net/' + container_name + '/' + blob_name + '?' + sas return sas_url,blob_name 时,我收到以下身份验证错误

sas_url

有谁知道为什么会发生这个错误?为了进一步澄清,将返回正确的 blob(最近更新/上传名称。我怀疑这与 Azure 美国政府和权限有关,但我不确定如何解决错误。我该如何解决这个问题?

以下是我使用的 Azure 依赖项:

<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:fd40ba66-b01e-008b-7350-5a1de4000000 Time:2021-06-05T21:22:51.5265808Z</Message>
  <AuthenticationErrorDetail>Signature did not match. String to sign used was rt 2021-06-05T23:22:33Z /blob/weedsmedia/weeds3d/MD-C2M-1-CALIB-1-GX010215.MP4 2020-06-12 b </AuthenticationErrorDetail>
</Error>

解决方法

我认为问题出在您的 generate_blob_sas 方法中的以下代码行:

account_key = key.CONNECTION_STRING_1

您似乎正在使用 storage account connection string 签署 SAS 令牌参数。您将需要使用 storage account key(key1 或 key2)为您的 SAS 令牌参数签名以获取 SAS 令牌。