基于标记和自定义安全属性允许对 Blob 进行读取访问

阅读本文,你将了解如何通过使用基于属性的访问控制 (ABAC) 条件来根据 Blob 索引标记和自定义安全属性允许对 Blob 的读取访问。 这样,可以更轻松地管理对 Blob 的访问。

先决条件

若要在 Microsoft Entra 租户中分配自定义安全属性并添加角色分配条件,你需要:

重要

默认情况下,全局管理员和其他管理员角色无权读取、定义或分配自定义安全属性。 如果不满足这些先决条件,条件编辑器中将不会显示主体/用户属性。

条件

如果用户具有与 Blob 索引标记匹配的自定义安全属性,则允许对 Blob 进行读取访问。 这是通过向角色分配添加条件完成的。

Diagram of role assignment with a condition.

例如,如果 Brenda 具有属性 Project=Baker,则她只能读取具有 Project=Baker Blob 索引标记的 Blob。 同样,Chandra 只能读取带有 Project=Cascade 的 Blob。

Diagram showing read access to blobs based on tags and custom security attributes.

下面是条件在代码中的呈现效果:

(
 (
  !(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})
 )
 OR 
 (
  @Principal[Microsoft.Directory/CustomSecurityAttributes/Id:Engineering_Project] StringEquals @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>]
 )
)

有关条件的详细信息,请参阅什么是 Azure 基于属性的访问控制 (Azure ABAC)?

步骤 1:添加新的自定义安全属性

  1. 登录 Azure 门户

  2. 单击“Microsoft Entra ID”>“自定义安全属性”。

  3. 添加一个名为 Project且值为 BakerCascade 的属性。 或使用现有属性。 有关详细信息,请参阅在 Microsoft Entra ID 中添加或停用自定义安全属性

    Screenshot of adding a custom security attribute.

步骤 2:将自定义安全属性分配给用户

  1. 在 Microsoft Entra ID 中创建安全组。

  2. 将用户添加为组的成员。

  3. 将值为 CascadeProject 属性分配给用户。 有关详细信息,请参阅为用户分配、更新、列出或删除自定义安全属性

    Screenshot of assigning a custom security attribute.

  4. 请确保单击“保存”以保存分配。

步骤 3:设置存储和 Blob 索引标记

  1. 创建与 Blob 索引标记功能兼容的存储帐户。 有关详细信息,请查看使用 Blob 索引标记管理和查找 Azure Blob 数据

  2. 在存储帐户中创建新容器,并将“公共访问级别”设置为“专用(不允许匿名访问)”。

  3. 将身份验证类型设置为“Azure AD 用户帐户”。

  4. 向容器上传文本文件,并设置以下 Blob 索引标记。

    文件 密钥
    Baker 文本文件 Project Baker
    Cascade 文本文件 Project Cascade

    提示

    有关 Blob 索引标记允许的字符的信息,请参阅设置 Blob 索引标记

步骤 4:使用条件分配存储 Blob 数据读取者角色

  1. 打开新的标签页,然后登录 Azure 门户

  2. 打开包含存储帐户的资源组。

  3. 单击“访问控制(IAM)”。

  4. 单击“角色分配”选项卡以查看在此范围内的角色分配。

  5. 单击“添加”>“添加角色分配”。

  6. 在“角色”选项卡中,选择存储 Blob 数据读取者角色。

  7. 在“成员”选项卡上,选择之前创建的安全组。

  8. (可选)在“描述”框中,输入“如果用户具有与 Blob 索引标记匹配的自定义安全属性,则允许对 Blob 进行读取访问”。

  9. 在“条件(可选)”选项卡上,单击“添加条件” 。

    随即显示“添加角色分配条件”页面。

  10. 在“添加操作”部分,单击“添加操作” 。

    随即会显示“选择操作”窗格。 此窗格是基于角色分配(将作为条件的目标)进行了筛选的数据操作列表。

  11. 单击“读取 blob”,然后单击“选择”。

  12. 在“生成表达式”部分,请单击“添加”。

  13. 输入以下设置:

    设置
    特性源 主体
    Attribute <attributeset>_Project
    操作员 StringEquals
    选项 Attribute
    特性源 资源
    特性 blob 索引标记 [键中的值]
    密钥 Project

    注意

    如果“主体”未作为“属性源”中的选项列出,请确保已按照步骤 1:添加新的自定义安全属性中所述定义了自定义安全属性。

    Screenshot of condition using principal attribute displayed in visual editor.

  14. 向上滚动到“编辑器类型”,然后单击“代码” 。

    条件应如下所示:

    (
     (
      !(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})
     )
     OR 
     (
      @Principal[Microsoft.Directory/CustomSecurityAttributes/Id:Engineering_Project] StringEquals @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>]
     )
    )
    
  15. 单击“保存”以保存条件。

  16. 在“查看 + 分配”选项卡上,单击“查看 + 分配”以分配具有条件的存储 Blob 数据读取者角色。

步骤 5:分配读取者角色

  • 重复上述步骤,在资源组范围内为安全组分配读取者角色。

    注意

    通常不需要分配“读取者”角色。 但是,这样做是为了使用 Azure 门户测试条件。

步骤 6:测试条件

  1. 在新窗口中,打开 Azure 门户

  2. 以使用 Project=Cascade 自定义安全属性创建的用户身份登录。

  3. 打开创建的存储帐户和容器。

  4. 请确保身份验证方法设置为“Azure AD 用户帐户”而不是“访问密钥”。

    Screenshot of storage container with test files.

  5. 单击 Baker 文本文件。

    不应能够查看或下载 Blob,应会显示授权失败消息。

  6. 单击 Cascade 文本文件。

    应能够查看和下载 Blob。

Azure PowerShell

还可使用 Azure PowerShell 添加角色分配条件。 以下命令显示如何添加条件。 有关信息,请参阅教程:使用 Azure PowerShell 添加角色分配条件以限制对 Blob 的访问

添加条件

  1. 使用 Connect-AzAccount 命令,并按照显示的说明以“基于角色的访问控制管理员”身份登录到你的目录。

    Connect-AzAccount -Environment AzureChinaCloud
    
  2. 使用 Get-AzRoleAssignment 获取分配到安全组的的角色分配。

    $groupRoleAssignment = Get-AzRoleAssignment -ObjectId <groupObjectId> -Scope <scope>
    
  3. 设置角色分配对象的 Condition 属性。 请务必使用属性集名称。

    $groupRoleAssignment.Condition="((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Principal[Microsoft.Directory/CustomSecurityAttributes/Id:Engineering_Project] StringEquals @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>]))"
    
  4. 设置角色分配对象的 ConditionVersion 属性。

    $groupRoleAssignment.ConditionVersion = "2.0"
    
  5. 使用 Set-AzRoleAssignment 更新角色分配。

    Set-AzRoleAssignment -InputObject $groupRoleAssignment
    

测试条件

  1. 在新的 PowerShell 窗口中,使用 Connect-AzAccount 命令以安全组的成员身份登录。

    Connect-AzAccount -Environment AzureChinaCloud
    
  2. 使用 New-AzStorageContext 设置存储帐户的上下文。

    $bearerCtx = New-AzStorageContext -StorageAccountName <accountName>
    
  3. 使用 Get-AzStorageBlob 尝试读取 Baker 文件。

    Get-AzStorageBlob -Container <containerName> -Blob <blobNameBaker> -Context $bearerCtx
    

    不应能够读取 Blob,应会显示授权失败消息。

    Get-AzStorageBlob : This request is not authorized to perform this operation using this permission. HTTP Status Code:
    403 - HTTP Error Message: This request is not authorized to perform this operation using this permission.
    ...
    
  4. 使用 Get-AzStorageBlob 尝试读取 Cascade 文件。

    Get-AzStorageBlob -Container <containerName> -Blob <blobNameCascade> -Context $bearerCtx
    You should be able to read the blob.
    AccountName: <storageAccountName>, ContainerName: <containerName>
    
    Name                 BlobType  Length          ContentType                    LastModified         AccessTier SnapshotT
                                                                                                                  ime
    ----                 --------  ------          -----------                    ------------         ---------- ---------
    CascadeFile.txt      BlockBlob 7               text/plain                     2021-04-24 05:35:24Z Hot
    

Azure CLI

还可使用 Azure CLI 添加角色分配条件。 以下命令显示如何添加条件。 有关信息,请参阅教程:使用 Azure CLI 添加角色分配条件以限制对 Blob 的访问

添加条件

  1. 使用 az login 命令,并按照显示的说明以“基于角色的访问控制管理员”身份登录到你的目录。

    az cloud set -n AzureChinaCloud
    az login
    
  2. 使用 az role assignment list 获取分配到安全组的的角色分配。

    az role assignment list --assignee <groupObjectId> --scope <scope>
    
  3. 使用以下格式创建 JSON 文件。

    {
        "canDelegate": null,
        "condition": "",
        "conditionVersion": "",
        "description": "",
        "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentId}",
        "name": "{roleAssignmentId}",
        "principalId": "{groupObjectId}",
        "principalName": "{principalName}",
        "principalType": "Group",
        "resourceGroup": "{resourceGroup}",
        "roleDefinitionId": "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1",
        "roleDefinitionName": "Storage Blob Data Reader",
        "scope": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}",
        "type": "Microsoft.Authorization/roleAssignments"
    }
    
  4. 更新 condition 属性。 请务必使用属性集名称。

    "condition": "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Principal[Microsoft.Directory/CustomSecurityAttributes/Id:Engineering_Project] StringEquals @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>]))",
    
  5. 更新 conditionVersion 属性。

    "conditionVersion": "2.0",
    
  6. 使用 az role assignment update 向角色分配添加条件。

    az role assignment update --role-assignment "./path/roleassignment.json"
    

测试条件

  1. 在新的命令窗口中,使用 Connect-AzAccount 命令以安全组的成员身份登录。

    az cloud set -n AzureChinaCloud
    az login
    
  2. 使用 az storage blob show 尝试读取 Baker 文件的属性。

    az storage blob show --account-name <storageAccountName> --container-name <containerName> --name <blobNameBaker> --auth-mode login
    

    不应能够读取 Blob,应会显示授权失败消息。

    You do not have the required permissions needed to perform this operation.
    ...
    
  3. 使用 az storage blob show 尝试读取 Cascade 文件的属性。

    az storage blob show --account-name <storageAccountName> --container-name <containerName> --name <blobNameCascade> --auth-mode login
    You should be able to read the blob.
    {
      "container": "<containerName>",
      "content": "",
      "deleted": false,
      "encryptedMetadata": null,
      "encryptionKeySha256": null,
      "encryptionScope": null,
    ...
    }
    

后续步骤