教程:使用 Azure PowerShell 添加角色分配条件以限制对 Blob 的访问
在大多数情况下,角色分配将授予访问 Azure 资源所需的权限。 但在某些情况下,你可能希望通过添加角色分配条件来提供更精细的访问控制。
在本教程中,你将了解如何执行以下操作:
- 将条件添加到角色分配
- 基于 blob 索引标记限制对 blob 的访问
重要
Azure 基于属性的访问控制 (Azure ABAC) 已正式发布 (GA),用于使用标准和高级存储帐户性能层中的 request
、resource
、environment
和 principal
属性控制对 Azure Blob 存储、Azure Data Lake Storage Gen2 和 Azure 队列的访问。 目前,“容器元数据”资源属性和“列出 Blob 操作的所含内容”请求属性处于预览状态。 有关 Azure 存储 ABAC 的完整功能状态信息,请参阅 Azure 存储中条件功能的状态。
有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Azure 预览版的补充使用条款。
先决条件
有关添加或编辑角色分配条件的先决条件的信息,请参阅有关条件的先决条件。
条件
在本教程中,你将使用特定的标记来限制对 blob 的访问。 例如,将条件添加到角色分配,使 Chandra 只能读取带有 Project=Cascade 标记的文件。
如果 Chandra 尝试读取不带 Project=Cascade 标记的 Blob,则访问将被拒绝。
下面是条件在代码中的呈现效果:
(
(
!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'}
AND NOT
SubOperationMatches{'Blob.List'})
)
OR
(
@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade'
)
)
步骤 1:安装必备组件
打开 PowerShell 窗口。
使用 Get-InstalledModule 检查已安装模块的版本。
Get-InstalledModule -Name Az Get-InstalledModule -Name Az.Resources Get-InstalledModule -Name Az.Storage
如果需要,请使用 Install-Module 安装所需版本的 Az、Az.Resources 和 Az.Storage 模块。
Install-Module -Name Az -RequiredVersion 5.5.0 Install-Module -Name Az.Resources -RequiredVersion 3.2.1 Install-Module -Name Az.Storage -RequiredVersion 2.5.2-preview -AllowPrerelease
关闭再重新打开 PowerShell 以刷新会话。
步骤 2:登录到 Azure
使用 Connect-AzAccount 命令,并按照显示的说明以用户访问管理员或所有者身份登录到你的目录。
Connect-AzAccount -Environment AzureChinaCloud
使用 Get-AzSubscription 列出你的所有订阅。
Get-AzSubscription
确定订阅 ID 并初始化变量。
$subscriptionId = "<subscriptionId>"
将订阅设置为活动订阅。
$context = Get-AzSubscription -SubscriptionId $subscriptionId Set-AzContext $context
步骤 3:创建用户
使用 New-MgUser 创建用户,或查找现有用户。 本教程使用 Chandra 作为示例。
初始化用户对象 ID 的变量。
$userObjectId = "<userObjectId>"
步骤 4:设置存储
使用 New-AzStorageAccount 创建与 Blob 索引功能兼容的存储帐户。 有关详细信息,请查看使用 Blob 索引标记管理和查找 Azure Blob 数据。
使用 New-AzStorageContainer 在存储帐户中创建新的 Blob 容器,并将“匿名访问级别”设置为“专用 (不允许匿名访问)”。
使用 Set-AzStorageBlobContent 将文本文件上传到该容器。
将以下 Blob 索引标记添加到文本文件。 有关详细信息,请参阅使用 blob 索引标记管理和查找 Azure Blob 存储中的数据。
注意
Blob 还能够存储任意用户定义的键值元数据。 尽管元数据与 Blob 索引标记类似,但你也必须将 Blob 索引标记与条件配合使用。
密钥 值 Project Cascade 将第二个文本文件上传到容器。
将以下 Blob 索引标记添加到第二个文本文件。
密钥 值 Project Baker 使用你所用的名称初始化以下变量。
$resourceGroup = "<resourceGroup>" $storageAccountName = "<storageAccountName>" $containerName = "<containerName>" $blobNameCascade = "<blobNameCascade>" $blobNameBaker = "<blobNameBaker>"
步骤 5:分配带条件的角色
初始化存储 Blob 数据读取者角色变量。
$roleDefinitionName = "Storage Blob Data Reader" $roleDefinitionId = "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1"
初始化资源组的范围。
$scope = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup"
初始化条件。
$condition = "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Cascade'))"
在 PowerShell 中,如果条件包含美元符号 ($),则必须使用反撇号 (`) 作为其前缀。 例如,此条件使用美元符号来描述标记键名称。
初始化条件版本和说明。
$conditionVersion = "2.0" $description = "Read access to blobs with the tag Project=Cascade"
使用 New-AzRoleAssignment 将带条件的存储 Blob 数据读取者角色分配到资源组范围的用户。
New-AzRoleAssignment -ObjectId $userObjectId -Scope $scope -RoleDefinitionId $roleDefinitionId -Description $description -Condition $condition -ConditionVersion $conditionVersion
这是一个输出示例:
RoleAssignmentId : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microso ft.Authorization/roleAssignments/<roleAssignmentId> Scope : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> DisplayName : Chandra SignInName : chandra@contoso.com RoleDefinitionName : Storage Blob Data Reader RoleDefinitionId : 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1 ObjectId : <userObjectId> ObjectType : User CanDelegate : False Description : Read access to blobs with the tag Project=Cascade ConditionVersion : 2.0 Condition : ((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/co ntainers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade'))
步骤 6:(可选)在 Azure 门户中查看条件
在 Azure 门户中打开资源组。
选择“访问控制 (IAM)”。
在“角色分配”选项卡上找到角色分配。
在“条件”列中,选择“查看/编辑”以查看条件。
步骤 7:测试条件
打开一个新的 PowerShell 窗口。
使用 Connect-AzAccount 以 Chandra 的身份登录。
Connect-AzAccount -Environment AzureChinaCloud
使用你所用的名称初始化以下变量。
$storageAccountName = "<storageAccountName>" $containerName = "<containerName>" $blobNameBaker = "<blobNameBaker>" $blobNameCascade = "<blobNameCascade>"
使用 New-AzStorageContext 创建特定的上下文,以便更轻松地访问你的存储帐户。
$bearerCtx = New-AzStorageContext -StorageAccountName $storageAccountName
使用 Get-AzStorageBlob 尝试读取 Baker 项目的文件。
Get-AzStorageBlob -Container $containerName -Blob $blobNameBaker -Context $bearerCtx
下面是一个输出示例。 请注意,由于添加了上述条件,因此无法读取该文件。
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. ErrorCode: AuthorizationPermissionMismatch ErrorMessage: This request is not authorized to perform this operation using this permission. RequestId: <requestId> Time: Sat, 24 Apr 2021 13:26:25 GMT At line:1 char:1 + Get-AzStorageBlob -Container $containerName -Blob $blobNameBaker -Con ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzStorageBlob], StorageException + FullyQualifiedErrorId : StorageException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.GetAzureStorageBlob Command
读取 Cascade 项目的文件。
Get-AzStorageBlob -Container $containerName -Blob $blobNameCascade -Context $bearerCtx
下面是一个输出示例。 你会发现,由于该项目带有 Project=Cascade 标记,因此可以读取该文件。
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
步骤 8:(可选)编辑条件
在另一个 PowerShell 窗口中,使用 Get-AzRoleAssignment 获取添加的角色分配。
$testRa = Get-AzRoleAssignment -Scope $scope -RoleDefinitionName $roleDefinitionName -ObjectId $userObjectId
编辑条件。
$condition = "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Cascade' OR @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Baker'))"
初始化条件和说明。
$testRa.Condition = $condition $testRa.Description = "Read access to blobs with the tag Project=Cascade or Project=Baker"
使用 Set-AzRoleAssignment 更新角色分配的条件。
Set-AzRoleAssignment -InputObject $testRa -PassThru
这是一个输出示例:
RoleAssignmentId : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microso ft.Authorization/roleAssignments/<roleAssignmentId> Scope : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> DisplayName : Chandra SignInName : chandra@contoso.com RoleDefinitionName : Storage Blob Data Reader RoleDefinitionId : 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1 ObjectId : <userObjectId> ObjectType : User CanDelegate : False Description : Read access to blobs with the tag Project=Cascade or Project=Baker ConditionVersion : 2.0 Condition : ((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/co ntainers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade' OR @Resource[Microsoft.S torage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Baker'))
步骤 9:清理资源
使用 Remove-AzRoleAssignment 删除添加的角色分配和条件。
Remove-AzRoleAssignment -ObjectId $userObjectId -RoleDefinitionName $roleDefinitionName -ResourceGroupName $resourceGroup
删除创建的存储帐户。
删除创建的用户。