Skip to content

Azure Blob Storage 連線與分享

Azure Blob Storage 的多種連線認證方式、SAS 產生方法、Stored Access Policy 管理,以及安全對外分享的完整指南。

概述

Azure Blob Storage 是 Azure 的物件儲存服務,支援多種存取方式:從生產環境的 DefaultAzureCredential(不需明文 Key)、到開發用的 Connection String、到對外分享用的 SAS Token。選擇正確的認證方式能在安全性與便利性之間取得平衡。

對外分享檔案時,SAS(Shared Access Signature)是最常用的機制:限定時間、限定權限、限定 IP,對方不需要 Azure 帳號就能存取。搭配 Stored Access Policy,還可以在不輪換 Account Key 的情況下隨時撤銷授權。

本文涵蓋從 Python SDK 程式連線到 GUI 工具、CLI 操作、分享給外部人員的完整場景,並附上常見排查技巧。

核心內容

認證方式選擇

方式適用情境安全性
DefaultAzureCredential生產環境(AKS、Workload Identity)
Connection String開發/測試
SAS Token臨時授權/對外分享中(依到期時間)
Account Key不建議用於生產環境

Python SDK 連線

三種連線方式對應不同場景:

DefaultAzureCredential(生產推薦):在 AKS 環境中,Pod 透過 Workload Identity 取得 Azure AD Token,完全不需要 Key/Secret。

Connection String:最簡單,直接包含帳號與 Key,適合本地開發。

SAS Token:傳入 credential=sas_token 即可,適合需要限定操作範圍的情境。

SAS 三種層級

層級產生位置適用情境
Account SASStorage Account 層級多容器存取(範圍廣,需謹慎)
Service SAS單一容器對外分享單一容器(推薦)
User Delegation SAS透過 Entra ID 身分簽發安全性最高,可用 Entra token 撤銷

容器層級 Service SAS 是對外分享的最佳選擇:範圍限定在單一容器、可搭配 Stored Access Policy、對方用 Storage Explorer 連接最直覺。

Stored Access Policy — 可撤銷的 SAS

純 SAS 一旦簽發,除非輪換整個 Account Key,否則無法撤銷。Stored Access Policy 解決此問題:

  1. 在容器的 Settings → Access policy 建立 Policy(例如 vendor-readonly-30d
  2. 用該 Policy 產生 SAS(Signing method 選 Account Key,不支援 User Delegation Key)
  3. 撤銷時刪除 Policy → 所有引用此 Policy 的 SAS 立即失效

限制: 每個容器最多 5 個 Policy、最多 30 秒生效延遲、只能建立在容器層級(不能在 Account 或單一 blob)。

Connection String / SAS Token / SAS URL 差異

三者是同一份授權的不同格式表示:

  • SAS Token:核心 query string(?sv=2022-11-02&ss=b&...&sig=...
  • Blob Service SAS URL:Storage Account 網址 + SAS Token(最常用的分享格式)
  • Connection String:結構化設定(BlobEndpoint=...;SharedAccessSignature=...,SDK 程式用)

實務建議:給對方 Blob Service SAS URL 一個就好,幾乎所有工具(Storage Explorer、AzCopy、瀏覽器)都吃這個格式。

Resource Types 設定說明

Account SAS 的 Resource Types 不是「服務類型」,而是 API 操作層級:

Resource Type操作層級典型用途
ServiceStorage Account 整體列出所有容器
Container容器層級列出容器內的 blob
Object單一 blob上傳、下載、刪除

一般「讓對方完整操作檔案」需勾 Container + Object;若不需要列容器清單則只選 Object。

Portal 產生 SAS 無法點擊的排查

「Generate SAS」按鈕 disable 的最常見原因(依排查順序):

  1. Allowed services / Resource types / Permissions 三個區塊都沒勾
  2. Start / Expiry time 不合理(Expiry 早於 Start 或為空)
  3. 帳號沒有讀取 Account Key 的權限(需 Storage Account Contributor 以上)
  4. Storage Account 禁用了 Shared Key Authorization(Configuration → Allow storage account key access)
  5. 瀏覽器問題(Ctrl+F5 強制刷新、換無痕視窗)

改用 Azure CLI容器層級 SAS(Shared access tokens 頁面) 通常能繞過大部分 Portal 問題。

關鍵要點

  • 生產環境用 DefaultAzureCredential,不要在程式碼中放 Connection String 或 Account Key
  • 對外分享用容器層級 Service SAS,不用 Account SAS(範圍太廣)
  • 需要撤銷能力時,必須搭配 Stored Access Policy(每個容器上限 5 個)
  • User Delegation SAS 安全性最高,但不支援 Portal 操作,需用 CLI/SDK
  • 給對方 Blob Service SAS URL 即可;Connection String 留給 SDK 程式用

實際應用

  • CI/CD 或 K8s 服務存取 Blob:在 AKS 使用 Workload Identity + DefaultAzureCredential,不需管理 Secret
  • 對外廠商短期交付檔案:建立容器 → 設定 Stored Access Policy → 簽發容器層級 SAS URL,到期或合作結束時刪除 Policy
  • 大量資料同步:用 AzCopy + SAS URL 進行單向或雙向同步(支援斷點續傳)
  • Python 腳本批次操作:用 BlobServiceClient + SAS URL 列出並下載 blob

部署設定參考

以下為實際操作時使用的完整指令與程式碼,供日後查詢與複製使用。

Python SDK 安裝

bash
pip install azure-storage-blob azure-identity

完整 Python 連線程式碼

DefaultAzureCredential(生產環境)

python
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

account_url = "https://<your-account-name>.blob.core.windows.net"
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(account_url=account_url, credential=credential)

Connection String(開發/測試)

python
from azure.storage.blob import BlobServiceClient

connection_string = "DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"
blob_service_client = BlobServiceClient.from_connection_string(connection_string)

SAS Token

python
from azure.storage.blob import BlobServiceClient

account_url = "https://<your-account-name>.blob.core.windows.net"
sas_token = "?sv=2022-11-02&ss=b&..."
blob_service_client = BlobServiceClient(account_url=account_url, credential=sas_token)

基本操作範例

python
container_name = "my-container"
blob_name = "folder/myfile.txt"
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)

# 上傳
with open("local_file.txt", "rb") as data:
    blob_client.upload_blob(data, overwrite=True)

# 下載
data = blob_client.download_blob().readall()

# 列出
container_client = blob_service_client.get_container_client(container_name)
for blob in container_client.list_blobs(name_starts_with="folder/"):
    print(blob.name, blob.size, blob.last_modified)

# 串流大檔案(分塊下載)
with open("large_file.bin", "wb") as f:
    download_stream = blob_client.download_blob()
    for chunk in download_stream.chunks():
        f.write(chunk)

Async 版本

python
from azure.storage.blob.aio import BlobServiceClient
from azure.identity.aio import DefaultAzureCredential

async def upload_async():
    credential = DefaultAzureCredential()
    async with BlobServiceClient(account_url=account_url, credential=credential) as client:
        blob_client = client.get_blob_client(container="my-container", blob="file.txt")
        await blob_client.upload_blob(b"data", overwrite=True)
        await credential.close()

Azure CLI 產生 SAS

bash
az login

# 容器層級 User Delegation SAS(推薦)
az storage container generate-sas \
  --account-name <storage-account> \
  --name <container-name> \
  --permissions rl \
  --expiry 2026-05-22T00:00:00Z \
  --auth-mode login \
  --as-user \
  --https-only \
  --output tsv

# Blob 層級 SAS URL(單一檔案)
az storage blob generate-sas \
  --account-name <storage-account> \
  --container-name <container-name> \
  --name <blob-name> \
  --permissions r \
  --expiry 2026-05-22T00:00:00Z \
  --auth-mode login \
  --as-user \
  --https-only \
  --full-uri \
  --output tsv

權限字母: r=Read、w=Write、d=Delete、l=List(容器)、a=Add、c=Create

Python SDK 使用 User Delegation SAS

python
from datetime import datetime, timedelta, timezone
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, generate_blob_sas, BlobSasPermissions

account_name = "<storage-account>"
account_url = f"https://{account_name}.blob.core.windows.net"

credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(account_url=account_url, credential=credential)

start = datetime.now(timezone.utc)
expiry = start + timedelta(days=7)

udk = blob_service_client.get_user_delegation_key(
    key_start_time=start,
    key_expiry_time=expiry,
)

sas_token = generate_blob_sas(
    account_name=account_name,
    container_name="<container>",
    blob_name="<blob>",
    user_delegation_key=udk,
    permission=BlobSasPermissions(read=True),
    expiry=expiry,
    start=start,
    protocol="https",
)

sas_url = f"{account_url}/<container>/<blob>?{sas_token}"

Python SDK 使用 SAS URL

python
from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient

# Service 層級 SAS URL
sas_url = "https://<account>.blob.core.windows.net/?sv=...&sig=..."
blob_service_client = BlobServiceClient(account_url=sas_url)

# 容器層級 SAS URL
container_sas_url = "https://<account>.blob.core.windows.net/<container>?sv=...&sig=..."
container_client = ContainerClient.from_container_url(container_sas_url)

# 單一 blob SAS URL
blob_sas_url = "https://<account>.blob.core.windows.net/<container>/<blob>?sv=...&sig=..."
blob_client = BlobClient.from_blob_url(blob_sas_url)
data = blob_client.download_blob().readall()

批次下載腳本

python
from azure.storage.blob import BlobServiceClient
from pathlib import Path

SAS_URL = "https://<account>.blob.core.windows.net/?sv=...&sig=..."
CONTAINER = "my-container"
PREFIX = "folder/"
LOCAL_DIR = Path("./downloads")

blob_service_client = BlobServiceClient(account_url=SAS_URL)
container_client = blob_service_client.get_container_client(CONTAINER)
LOCAL_DIR.mkdir(parents=True, exist_ok=True)

for blob in container_client.list_blobs(name_starts_with=PREFIX):
    blob_client = container_client.get_blob_client(blob.name)
    local_path = LOCAL_DIR / blob.name
    local_path.parent.mkdir(parents=True, exist_ok=True)
    print(f"Downloading {blob.name} ({blob.size} bytes)...")
    with open(local_path, "wb") as f:
        f.write(blob_client.download_blob().readall())

非程式工具指令

AzCopy

powershell
azcopy login

# 上傳
azcopy copy "C:\data\file.txt" "https://<account>.blob.core.windows.net/<container>/file.txt"

# 同步資料夾
azcopy sync "C:\data" "https://<account>.blob.core.windows.net/<container>" --recursive

rclone 掛載(Windows 磁碟機)

powershell
winget install Rclone.Rclone
rclone config   # 設定 Azure Blob 後端
rclone mount azure:my-container Z: --vfs-cache-mode full

完整檔案操作的 Account SAS 設定

Allowed services:
  ✅ Blob

Allowed resource types:
  ✅ Container  ← 列清單需要
  ✅ Object     ← 操作單一檔案需要

Allowed permissions:
  ✅ Read ✅ Write ✅ Delete ✅ List ✅ Add ✅ Create

Allowed protocols:
  ✅ HTTPS only

對外分享訊息範本

這是你可以存取 Blob Storage 的 SAS URL:
https://<account>.blob.core.windows.net/?sv=...&sig=...

權限:Read / Write / List / Delete
有效期限:2026/XX/XX(UTC)

使用方式:
1. 安裝 Azure Storage Explorer
2. 開啟後選「Attach to a resource」→「Storage account」→「SAS URL」
3. 貼上上面的連結即可

(連結請妥善保管,不要轉傳給第三方)

相關概念

來源