You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OAuth 2.0令牌上传文件至Azure Blob Storage时遇401错误求助

问题:使用OAuth 2.0令牌通过PUT请求上传Azure Blob Storage返回401未授权

我需要将文件上传(后续还需下载)至Azure Blob Storage,但不允许使用Storage SDK,只能用requests、json这类预加载库。目前已经成功拿到OAuth 2.0令牌,但构造PUT请求上传文件时始终返回401错误。

获取令牌的代码能正常返回令牌,而且用Storage SDK可以成功上传文件(说明应用注册和权限配置没问题)。

获取令牌代码:

# Set the request url
url = f'https://login.microsoftonline.com/{tenant}/oauth2/token'

# Set the request headers
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
resource = 'https://management.azure.com/'

# Set the request body
body = {
    'grant_type': 'client_credentials',
    'client_id': client_id,
    'client_secret': client_secret,
    'resource': resource
}

# Make the POST request to the authentication endpoint
response = requests.post(url, headers=headers, data=body)

# Parse the JSON response
response_json = json.loads(response.text)

# Save to variable
oauth_token = response_json['access_token']

上传文件的PUT请求代码:

# Code to upload file to blob storage

# Set the request url
endpoint  = f'https://{storage_account_name}.blob.core.windows.net/{container_name}/{blob_name}'

# Open the file to be uploaded
with open(blob_name, "rb") as f:
    # Get file size
    file_size = str(len(f.read()))
    # Get date
    now = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
    # Move the pointer back to the beginning of the file
    f.seek(0)
    # Set the headers for the request
    headers = {
        "Authorization": f"Bearer {oauth_token}",
        "x-ms-version":"2020-04-08",
        "Content-Length": file_size,
        "x-ms-blob-type": "BlockBlob",
        "Date": now
    }
    # Send the PUT request to upload the file
    response = requests.put(endpoint, headers=headers, data=f)

response.status_code

请求返回状态码为401。我试过加更多请求头字段,也删除重建过应用注册,但还是没法访问资源,求帮忙!


解决方案

你遇到的401问题核心原因是获取OAuth令牌时指定的resource参数不对。

在你的令牌获取代码里,resource设成了https://management.azure.com/,这个资源对应的是Azure管理API的权限,不是Blob存储服务的权限。要访问Blob Storage,得把resource改成https://storage.azure.com/(旧版API也可以用https://<storage-account-name>.blob.core.windows.net/,但前者是通用值更推荐)。

修改后的令牌获取代码:

# Set the request url
url = f'https://login.microsoftonline.com/{tenant}/oauth2/token'

# Set the request headers
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# 修正resource为Blob Storage的资源标识符
resource = 'https://storage.azure.com/'

# Set the request body
body = {
    'grant_type': 'client_credentials',
    'client_id': client_id,
    'client_secret': client_secret,
    'resource': resource
}

# Make the POST request to the authentication endpoint
response = requests.post(url, headers=headers, data=body)

# Parse the JSON response
response_json = json.loads(response.text)

# Save to variable
oauth_token = response_json['access_token']

额外优化建议:

  1. 用x-ms-date替代Date请求头:Azure Blob Storage API更推荐用x-ms-date指定请求的UTC时间,能避免客户端本地时间设置的潜在问题。修改headers里的Date为x-ms-date:
    headers = {
        "Authorization": f"Bearer {oauth_token}",
        "x-ms-version":"2020-04-08",
        "Content-Length": file_size,
        "x-ms-blob-type": "BlockBlob",
        "x-ms-date": now  # 替换原来的Date
    }
    
  2. 更高效的文件大小计算方式:当前用len(f.read())会把整个文件读进内存,大文件场景很不友好,可以改成:
    import os
    file_size = str(os.path.getsize(blob_name))
    
    不用打开文件就能获取大小,节省内存。

修改后重新获取令牌再执行上传请求,应该就能解决401的问题了。既然你已经确认应用注册的权限配置没问题(SDK能正常上传),只要令牌的资源匹配,就能通过认证。

内容的提问来源于stack exchange,提问作者Emilio A.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:30:57