你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

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

本文介绍如何使用基于属性的访问控制 (ABAC) 条件,允许基于 Blob 索引标记和自定义安全属性的 Blob 读取访问权限。 这样就可以更轻松地管理对 Blob 的访问。

先决条件

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

重要

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

条件

在本文中,如果用户具有与 Blob 索引标记匹配的自定义安全属性,则可以允许读取对 Blob 的访问。 这可以通过向角色分配添加条件来实现。

具有条件的角色分配关系图。

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

关系图显示基于标记和自定义安全属性对 Blob 的读取权限。

下面是代码中条件的样子:

(
 (
  !(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 中的添加或停用自定义安全属性

    添加自定义安全属性的屏幕截图。

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

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

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

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

    分配自定义安全属性的屏幕截图。

  4. 请务必单击“ 保存 ”以保存作业。

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

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

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

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

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

    文件 密钥 价值
    Baker 文本文件 项目 面包师傅
    级联文本文件 项目 级联

    小提示

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

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

  1. 打开新选项卡并登录到 Azure 门户

  2. 打开具有存储帐户的资源组。

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

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

  5. 单击添加>添加角色分配

  6. 角色选项卡上,选择存储 Blob 数据读取者角色。

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

  8. (可选)在 “说明 ”框中, 如果用户具有与 Blob 索引标记匹配的自定义安全属性,请输入对 Blob 的读取访问权限

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

    此时会显示“添加角色分配条件”页。

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

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

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

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

  13. 输入以下设置:

    设置 价值
    特性源 校长
    特征 <attributeset>_Project
    操作员 StringEquals
    选项 特征
    特性源 资源
    特征 blob 索引标记 [键中的值]
    密钥 项目

    注释

    如果未在属性源中将主体列为选项,请确保已定义自定义安全属性,如 步骤 1 中所述:添加新的自定义安全属性

    在可视化编辑器中使用主要属性的条件的屏幕截图。

  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 用户帐户 ,而不是 访问密钥

    包含测试文件的存储容器的屏幕截图。

  5. 单击 Baker 文本文件。

    你应该无法查看或下载 Blob,并且应看到授权失败的消息。

  6. 单击级联文本文件。

    您应该能够查看和下载数据块。

Azure PowerShell

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

添加条件

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

    Connect-AzAccount
    
  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
    
  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 命令行界面)

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

添加条件

  1. 请执行 az login 命令,并按照显示的说明,以基于角色的访问控制管理员身份登录到您的目录。

    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. 在新命令窗口中,使用 az login 命令以安全组成员身份登录。

    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,
    ...
    }
    

后续步骤