使用 .NET 为容器创建服务 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)

本文介绍了如何使用存储帐户密钥通过面向 .NET 的 Azure Blob 存储客户端库为容器创建服务 SAS。

关于服务 SAS

服务 SAS 将使用帐户访问密钥进行签名。 可以使用 StorageSharedKeyCredential 类创建用于为服务 SAS 签名的凭据。

还可以使用存储访问策略来定义 SAS 的权限和持续时间。 如果提供现有存储访问策略的名称,则该策略与 SAS 关联。 若要详细了解存储访问策略,请参阅定义存储访问策略。 如果未提供存储访问策略,可通过本文中的代码示例来了解如何定义 SAS 的权限和持续时间。

为容器创建服务 SAS

以下代码示例演示如何为容器资源创建服务 SAS。 首先,代码通过检查 CanGenerateSasUri 属性来验证是否已通过共享密钥凭据为 BlobContainerClient 对象授权。 然后,它通过 BlobSasBuilder 类生成服务 SAS,并调用 GenerateSasUri 以基于客户端和生成器对象创建服务 SAS URI。

public static async Task<Uri> CreateServiceSASContainer(
    BlobContainerClient containerClient,
    string storedPolicyName = null)
{
    // Check if BlobContainerClient object has been authorized with Shared Key
    if (containerClient.CanGenerateSasUri)
    {
        // Create a SAS token that's valid for one day
        BlobSasBuilder sasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = containerClient.Name,
            Resource = "c"
        };

        if (storedPolicyName == null)
        {
            sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddDays(1);
            sasBuilder.SetPermissions(BlobContainerSasPermissions.Read);
        }
        else
        {
            sasBuilder.Identifier = storedPolicyName;
        }

        Uri sasURI = containerClient.GenerateSasUri(sasBuilder);

        return sasURI;
    }
    else
    {
        // Client object is not authorized via Shared Key
        return null;
    }
}

使用服务 SAS 为客户端对象授权

以下代码示例演示如何使用服务 SAS 为 BlobContainerClient 对象授权。 此客户端对象可用于根据 SAS 授予的权限对容器资源执行操作。

首先,创建使用帐户访问密钥签名的 BlobServiceClient 对象:

string accountName = "<storage-account-name>";
string accountKey = "<storage-account-key";
StorageSharedKeyCredential storageSharedKeyCredential =
    new(accountName, accountKey);
BlobServiceClient blobServiceClient = new BlobServiceClient(
    new Uri($"https://{accountName}.blob.core.chinacloudapi.cn"),
    storageSharedKeyCredential);

然后,如前面的例子所示,生成服务 SAS,并使用 SAS 授权 BlobContainerClient 对象:

// Create a Uri object with a service SAS appended
BlobContainerClient containerClient = blobServiceClient
    .GetBlobContainerClient("sample-container");
Uri containerSASURI = await CreateServiceSASContainer(containerClient);

// Create a container client object representing 'sample-container' with SAS authorization
BlobContainerClient containerClientSAS = new BlobContainerClient(containerSASURI);

定义存储访问策略

存储访问策略对服务器端的服务级别共享访问签名 (SAS) 提供额外的一层控制。 建立存储访问策略可将共享访问签名分组以及对该策略绑定的签名施加其他限制。

可使用存储访问策略更改签名的开始时间、到期时间或权限。 也可以使用存储访问策略在颁发签名后将其撤消。 本部分重点介绍 Blob 容器,但文件共享、队列和表也支持存储访问策略。

若要管理容器资源上的存储访问策略,请调用 BlobContainerClient 对象中的以下方法之一:

创建或修改存储访问策略

一个资源一次最多可以设置 5 个访问策略。 每个 SignedIdentifier 字段(及其唯一的 Id 字段)对应于一个访问策略。 一次试图设置超过 5 个访问策略会导致服务返回状态代码“400 (Bad Request)”。

下面的代码示例演示如何在容器资源上创建两个存储访问策略:

public static async Task CreateStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    // Create a stored access policy with read and write permissions, valid for one day
    List<BlobSignedIdentifier> signedIdentifiers = new List<BlobSignedIdentifier>
    {
        new BlobSignedIdentifier
        {
            Id = "sample-read-write-policy",
            AccessPolicy = new BlobAccessPolicy
            {
                StartsOn = DateTimeOffset.UtcNow,
                ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
                Permissions = "rw"
            }
        },
        new BlobSignedIdentifier
        {
            Id = "sample-read-policy",
            AccessPolicy = new BlobAccessPolicy
            {
                StartsOn = DateTimeOffset.UtcNow,
                ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
                Permissions = "r"
            }
        }
    };

    // Set the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

还可以修改现有策略。 下面的代码示例演示如何修改单个存储访问策略,以更新该策略的到期日期:

public static async Task ModifyStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    BlobContainerAccessPolicy accessPolicy = await containerClient.GetAccessPolicyAsync();
    List<BlobSignedIdentifier> signedIdentifiers = accessPolicy.SignedIdentifiers.ToList();

    // Modify the expiration date a single policy
    var samplePolicy = signedIdentifiers.FirstOrDefault(item => item.Id == "sample-read-policy");
    samplePolicy.AccessPolicy.PolicyExpiresOn = DateTimeOffset.UtcNow.AddDays(7);

    // Update the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

撤销或删除存储访问策略

若要撤消存储访问策略,可以删除它,通过更改有签名的标识符对其进行重命名,或将过期时间更改为过去的某个值。 更改签名标识符会中断任何现有签名与存储访问策略之间的关联。 将过期时间更改为过去的某个值会导致所有关联的签名过期。 删除或修改存储访问策略会立即影响与之关联的所有共享访问签名。

下面的代码示例演示如何通过更改已签名标识符的 Id 属性来撤销策略:

public static async Task RevokeStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    BlobContainerAccessPolicy accessPolicy = await containerClient.GetAccessPolicyAsync();
    List<BlobSignedIdentifier> signedIdentifiers = accessPolicy.SignedIdentifiers.ToList();

    // Revoke a single policy by changing its name
    var samplePolicy = signedIdentifiers.FirstOrDefault(item => item.Id == "sample-read-policy");
    samplePolicy.Id = "sample-read-policy-revoke";

    // Update the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

还可以通过调用 permissions 参数为空的 SetAccessPolicyAsync 从容器资源中删除所有访问策略。 以下示例介绍如何从指定的容器中删除所有存储访问策略:

public static async Task DeleteStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    // Remove all stored access policies for the container resource
    await containerClient.SetAccessPolicyAsync();
}

资源

若要详细了解如何使用用于 .NET 的 Azure Blob 存储客户端库来创建服务 SAS,请参阅以下资源。

客户端库资源

另请参阅