Compartir a través de

使用 Python 为容器或 blob 创建用户委托 SAS

使用共享访问签名 (SAS),可以授予对存储帐户中容器和 blob 的有限访问权限。 创建 SAS 时,需要指定其约束条件,包括允许客户端访问哪些 Azure 存储资源、它们对这些资源具有哪些权限,以及 SAS 的有效期。

每个 SAS 均使用密钥进行签名。 可通过以下两种方式之一对 SAS 进行签名:

  • 使用通过 Microsoft Entra 凭据创建的密钥。 使用 Microsoft Entra 凭据签名的 SAS 是用户委托 SAS。 必须为创建用户委托 SAS 的客户端分配一个 Azure RBAC 角色,该角色包括 Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey 操作。 若要了解详细信息,请参阅创建用户委托 SAS
  • 使用存储帐户密钥。 服务 SAS 和帐户 SAS 均使用存储帐户密钥进行签名。 创建服务 SAS 的客户端必须具有对帐户密钥的直接访问权限,或分配有 Microsoft.Storage/storageAccounts/listkeys/action 权限。 若要了解详细信息,请参阅创建服务 SAS创建帐户 SAS

注意

用户委托 SAS 为使用存储帐户密钥签名的 SAS 提供更高的安全性。 Microsoft 建议尽可能使用用户委托 SAS。 有关详细信息,请参阅向具有共享访问签名的数据授予有限的访问权限 (SAS)

本文介绍如何使用适用于 Python 的 Azure 存储客户端库通过 Microsoft Entra 凭据为容器或 blob 创建用户委托 SAS。

关于用户委托 SAS

可使用 Microsoft Entra 凭据或帐户密钥来保护用于访问容器或 Blob 的 SAS 令牌。 使用 Microsoft Entra 凭据保护的 SAS 称为用户委派 SAS,因为用于签署 SAS 的 OAuth 2.0 令牌是代表用户请求的。

Azure 建议你尽可能使用 Microsoft Entra 凭据,而不要使用更容易受到安全威胁的帐户密钥,这是安全性方面的最佳做法。 当应用程序设计需要共享访问签名时,请使用 Microsoft Entra 凭据创建可提供超高安全性的用户委派 SAS。 有关用户委托 SAS 的详细信息,请参阅创建用户委托 SAS

注意

拥有有效 SAS 的任何客户端都可以访问该 SAS 允许的存储帐户中的数据。 防止 SAS 被恶意使用或意料之外的使用很重要。 请谨慎分发 SAS,并制定撤销受到安全威胁的 SAS 的计划。

有关共享访问签名的详细信息,请参阅使用共享访问签名 (SAS) 授予对 Azure 存储资源的有限访问权限

分配可访问数据的 Azure 角色

当 Microsoft Entra 安全主体尝试访问数据时,该安全主体必须具有对资源的访问权限。 不管安全主体是 Azure 中的托管标识,还是在开发环境中运行代码的 Microsoft Entra 用户帐户,都必须为安全主体分配一个 Azure 角色,由该角色授权访问数据。 有关通过 Azure RBAC 分配权限的信息,请参阅分配用于访问 Blob 数据的 Azure 角色

设置项目

要使用本文中的代码示例,请按照以下步骤设置项目。

安装包

使用 pip install 安装以下包:

pip install azure-storage-blob azure-identity

设置应用代码

然后,添加以下 import 指令:

from azure.identity import DefaultAzureCredential
from azure.storage.blob import (
    BlobServiceClient,
    ContainerClient,
    BlobClient,
    BlobSasPermissions,
    ContainerSasPermissions,
    UserDelegationKey,
    generate_container_sas,
    generate_blob_sas
)

获取经过身份验证的令牌凭据

若要获取令牌凭据,以便代码用它来授权对 Blob 存储的请求,请创建 DefaultAzureCredential 类的实例。 要详细了解如何使用 DefaultAzureCredential 类来授权托管标识访问 Blob 存储,请参阅适用于 Python 的 Azure 标识客户端库

以下代码片段演示了如何获取经身份验证的令牌凭据并使用它来为 Blob 存储创建服务客户端:

# Construct the blob endpoint from the account name
account_url = "https://<storage-account-name>.blob.core.chinacloudapi.cn"

#Create a BlobServiceClient object using DefaultAzureCredential
blob_service_client = BlobServiceClient(account_url, credential=DefaultAzureCredential())

要详细了解如何通过 Python SDK 从应用程序授权访问 Blob 存储,请参阅向 Azure 服务验证 Python 应用身份

获取用户委托密钥

每个 SAS 均使用密钥进行签名。 若要创建用户委托 SAS,必须首先请求用户委托密钥,然后使用该密钥对 SAS 进行签名。 用户委派密钥与用于对服务 SAS 或帐户 SAS 签名的帐户密钥类似,只不过它依赖于 Microsoft Entra 凭据。 当客户端使用 OAuth 2.0 令牌请求用户委托密钥时,Blob 存储将代表该用户返回用户委托密钥。

拥有用户委托密钥后,你就可以在该密钥的生存期内使用该密钥创建任意数量的用户委托共享访问签名。 用户委派密钥与用于获取该密钥的 OAuth 2.0 令牌相互独立,因此只要密钥仍有效,就不必续订令牌。 可以指定密钥保持有效的时间长度,最长为七天。

使用以下方法之一请求用户委托密钥:

以下代码示例演示如何请求用户委托密钥:

def request_user_delegation_key(self, blob_service_client: BlobServiceClient) -> UserDelegationKey:
    # Get a user delegation key that's valid for 1 day
    delegation_key_start_time = datetime.datetime.now(datetime.timezone.utc)
    delegation_key_expiry_time = delegation_key_start_time + datetime.timedelta(days=1)

    user_delegation_key = blob_service_client.get_user_delegation_key(
        key_start_time=delegation_key_start_time,
        key_expiry_time=delegation_key_expiry_time
    )

    return user_delegation_key

创建用户委托 SAS

你可以根据应用的需求为容器或 Blob 创建用户委托 SAS。

获取用户委托密钥后,可以创建用户委托 SAS。 可以使用以下方法创建用户委派 SAS 向容器资源委派有限的访问权限:

用于对 SAS 进行签名的用户委派密钥将会作为 user_delegation_key 参数传递到该方法。 允许的权限将作为 permission 参数传递给该方法,并在 ContainerSasPermissions 类中进行定义。

下面的代码示例演示如何为容器创建用户委派 SAS:

def create_user_delegation_sas_container(self, container_client: ContainerClient, user_delegation_key: UserDelegationKey):
    # Create a SAS token that's valid for one day, as an example
    start_time = datetime.datetime.now(datetime.timezone.utc)
    expiry_time = start_time + datetime.timedelta(days=1)

    sas_token = generate_container_sas(
        account_name=container_client.account_name,
        container_name=container_client.container_name,
        user_delegation_key=user_delegation_key,
        permission=ContainerSasPermissions(read=True),
        expiry=expiry_time,
        start=start_time
    )

    return sas_token

使用用户委托 SAS 为客户端对象授权

你可以使用用户委托 SAS 来授权客户端对象根据 SAS 授予的权限对容器或 blob 执行操作。

以下代码示例显示了如何使用在较早的示例中创建的用户委派 SAS 来授权 ContainerClient 对象。 此客户端对象可用于根据 SAS 授予的权限对容器资源执行操作。

# The SAS token string can be appended to the resource URL with a ? delimiter
# or passed as the credential argument to the client constructor
sas_url = f"{container_client.url}?{sas_token}"

# Create a ContainerClient object with SAS authorization
container_client_sas = ContainerClient.from_container_url(container_url=sas_url)

资源

要详细了解如何使用适用于 Python 的 Azure Blob 存储客户端库来创建用户委派 SAS,请参阅以下资源。

代码示例

REST API 操作

Azure SDK for Python 包含基于 Azure REST API 而生成的库,允许你通过熟悉的 Python 范例与 REST API 操作进行交互。 用于获取用户委派密钥的客户端库方法使用以下 REST API 操作:

客户端库资源

另请参阅

  • 本文是 Python 版 Blob 存储开发人员指南的一部分。 若要了解详细信息,请参阅生成 Python 应用中的开发人员指南文章的完整列表。