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

使用密钥保管库和 Azure PowerShell 管理存储帐户密钥(旧版)

重要

Key Vault 托管存储帐户密钥(旧版)按原样受支持,未再计划更新。 只有不高于 2018-03-28 的 SAS 定义已签名的存储服务版本才支持帐户 SAS。

重要

我们建议使用 Azure 存储与 Azure Active Directory (Azure AD) 的集成,这是 Microsoft 推出的基于云的标识和访问管理服务。 Azure AD 集成适用于 Azure Blob 和队列,提供对 Azure 存储的基于 OAuth2 令牌的访问(类似于 Azure Key Vault)。 Azure AD 允许使用应用程序标识或用户标识(而不是存储帐户凭据)对客户端应用程序进行身份验证。 在 Azure 上运行时,可以使用 Azure AD 托管标识。 托管标识消除了客户端身份验证的需要,并可以在应用程序中存储凭据,或者将凭据与应用程序一同存储。 仅在无法实施 Azure AD 身份验证的情况下使用以下解决方案。

Azure 存储帐户使用由帐户名和密钥构成的凭据。 密钥是自动生成的,充当密码而不是加密密钥。 Key Vault 通过在存储帐户中定期重新生成存储帐户密钥来管理存储帐户密钥,并提供共享访问签名令牌,以便对存储帐户中的资源进行委托访问。

可以使用 Key Vault 托管的存储帐户密钥功能列出(同步) Azure 存储帐户中的密钥,并定期重新生成(轮换)密钥。 可以管理存储帐户和经典存储帐户的密钥。

使用托管的存储帐户密钥功能时,请注意以下要点:

  • 响应调用方时永远不会返回密钥值。
  • 只有 Key Vault 能够管理存储帐户密钥。 不要自行管理密钥,并避免干扰 Key Vault 进程。
  • 只有单个 Key Vault 对象能够管理存储帐户密钥。 不要允许从多个对象进行密钥管理。
  • 只使用 Key Vault 重新生成密钥。 不要手动重新生成存储帐户密钥。

重要

直接在存储帐户中重新生成密钥会中断托管存储帐户设置,并且会使正在使用的 SAS 令牌失效并造成中断。

注意

本文使用 Azure Az PowerShell 模块,这是与 Azure 交互时推荐使用的 PowerShell 模块。 若要开始使用 Az PowerShell 模块,请参阅安装 Azure PowerShell。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

服务主体应用程序 ID

Azure AD 租户为每个已注册的应用程序提供服务主体。 此服务主体充当应用程序 ID,该 ID 在授权设置过程中用于通过 Azure RBAC 访问其他 Azure 资源。

Key Vault 是已在所有 Azure AD 租户中预先注册的 Microsoft 应用程序。 Key Vault 注册到每个 Azure 云中的同一个应用程序 ID 下。

租户 应用程序 ID
Azure AD Azure Government 7e7c393b-45d0-48b1-a35e-2905ddf8183c
Azure AD Azure 公共 cfa8b339-82a2-471a-a3c9-0fc0be7a4093
其他 任意 cfa8b339-82a2-471a-a3c9-0fc0be7a4093

先决条件

若要完成本指南,必须先执行以下操作:

管理存储帐户密钥

连接到 Azure 帐户

使用 Connect-AzAccount cmdlet 对 PowerShell 会话进行身份验证。

Connect-AzAccount

如果你有多个 Azure 订阅,可以使用 Get-AzSubscription cmdlet 列出这些订阅,并指定要与 Set-AzContext cmdlet 结合使用的订阅。

Set-AzContext -SubscriptionId <subscriptionId>

设置变量

首先,通过以下步骤设置 PowerShell cmdlet 使用的变量。 请确保更新“YourResourceGroupName”、“YourStorageAccountName”和“YourKeyVaultName”占位符,并将 $keyVaultSpAppId 设置为 cfa8b339-82a2-471a-a3c9-0fc0be7a4093(如上文服务主体应用程序 ID 中指定的那样)。

我们还将使用 Azure PowerShell Get-AzContextGet-AzStorageAccount cmdlet 来获取你的用户 ID,以及 Azure 存储帐户的上下文。

$resourceGroupName = <YourResourceGroupName>
$storageAccountName = <YourStorageAccountName>
$keyVaultName = <YourKeyVaultName>
$keyVaultSpAppId = "cfa8b339-82a2-471a-a3c9-0fc0be7a4093"
$storageAccountKey = "key1" #(key1 or key2 are allowed)

# Get your User Id
$userId = (Get-AzContext).Account.Id

# Get a reference to your Azure storage account
$storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName -StorageAccountName $storageAccountName

注意

对于经典存储帐户,请使用“primary”和“secondary”作为 $storageAccountKey
对于经典存储帐户,请使用 'Get-AzResource -Name "ClassicStorageAccountName" -ResourceGroupName $resourceGroupName' 而不是 'Get-AzStorageAccount'

向 Key Vault 授予对你的存储帐户的访问权限

只有在授权 Key Vault 访问你的存储帐户之后,它才可以访问和管理存储帐户密钥。 Key Vault 应用程序标识需要有权列出和重新生成存储帐户的密钥。 可通过 Azure 内置角色存储帐户密钥操作员服务角色启用这些权限。

使用 Azure PowerShell New-AzRoleAssignment cmdlet 将此角色分配到 Key Vault 服务主体,以将范围限定为你的存储帐户。

# Assign Azure role "Storage Account Key Operator Service Role" to Key Vault, limiting the access scope to your storage account. For a classic storage account, use "Classic Storage Account Key Operator Service Role."
New-AzRoleAssignment -ApplicationId $keyVaultSpAppId -RoleDefinitionName 'Storage Account Key Operator Service Role' -Scope $storageAccount.Id

成功完成角色分配后,应会看到类似于以下示例的输出:

RoleAssignmentId   : /subscriptions/03f0blll-ce69-483a-a092-d06ea46dfb8z/resourceGroups/rgContoso/providers/Microsoft.Storage/storageAccounts/sacontoso/providers/Microsoft.Authorization/roleAssignments/189cblll-12fb-406e-8699-4eef8b2b9ecz
Scope              : /subscriptions/03f0blll-ce69-483a-a092-d06ea46dfb8z/resourceGroups/rgContoso/providers/Microsoft.Storage/storageAccounts/sacontoso
DisplayName        : Azure Key Vault
SignInName         :
RoleDefinitionName : storage account Key Operator Service Role
RoleDefinitionId   : 81a9662b-bebf-436f-a333-f67b29880f12
ObjectId           : 93c27d83-f79b-4cb2-8dd4-4aa716542e74
ObjectType         : ServicePrincipal
CanDelegate        : False

如果 Key Vault 已添加到存储帐户中的角色,则你会收到“角色分配已存在”错误。 还可以使用 Azure 门户中存储帐户的“访问控制(IAM)”页验证角色分配。

向托管存储帐户授予用户帐户权限

使用 Azure PowerShell Set-AzKeyVaultAccessPolicy cmdlet 更新 Key Vault 访问策略,并向用户帐户授予存储帐户权限。

# Give your user principal access to all storage account permissions, on your Key Vault instance

Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -UserPrincipalName $userId -PermissionsToStorage get, list, delete, set, update, regeneratekey, getsas, listsas, deletesas, setsas, recover, backup, restore, purge

请注意,Azure 门户中存储帐户的“访问策略”页不会显示存储帐户的权限。

将托管存储帐户添加到 Key Vault 实例

使用 Azure PowerShell Add-AzKeyVaultManagedStorageAccount cmdlet 在 Key Vault 实例中创建托管存储帐户。 -DisableAutoRegenerateKey 开关指定不重新生成存储帐户密钥。

# Add your storage account to your Key Vault's managed storage accounts

Add-AzKeyVaultManagedStorageAccount -VaultName $keyVaultName -AccountName $storageAccountName -AccountResourceId $storageAccount.Id -ActiveKeyName $storageAccountKey -DisableAutoRegenerateKey

成功添加不重新生成密钥的存储帐户后,应会看到类似于以下示例的输出:

Id                  : https://kvcontoso.vault.azure.net:443/storage/sacontoso
Vault Name          : kvcontoso
AccountName         : sacontoso
Account Resource Id : /subscriptions/03f0blll-ce69-483a-a092-d06ea46dfb8z/resourceGroups/rgContoso/providers/Microsoft.Storage/storageAccounts/sacontoso
Active Key Name     : key1
Auto Regenerate Key : False
Regeneration Period : 90.00:00:00
Enabled             : True
Created             : 11/19/2018 11:54:47 PM
Updated             : 11/19/2018 11:54:47 PM
Tags                :

启用密钥重新生成

如果希望 Key Vault 定期重新生成存储帐户密钥,可以使用 Azure PowerShell Add-AzKeyVaultManagedStorageAccount cmdlet 设置重新生成周期。 此示例将重新生成周期设置为 30 天。 当需要轮换时,Key Vault 将重新生成非活动状态的密钥,然后将新创建的密钥设置为活动密钥。 在任何时间都只有一个密钥用于颁发 SAS 令牌。 这就是活动密钥。

$regenPeriod = [System.Timespan]::FromDays(30)

Add-AzKeyVaultManagedStorageAccount -VaultName $keyVaultName -AccountName $storageAccountName -AccountResourceId $storageAccount.Id -ActiveKeyName $storageAccountKey -RegenerationPeriod $regenPeriod

成功添加重新生成密钥的存储帐户后,应会看到类似于以下示例的输出:

Id                  : https://kvcontoso.vault.azure.net:443/storage/sacontoso
Vault Name          : kvcontoso
AccountName         : sacontoso
Account Resource Id : /subscriptions/03f0blll-ce69-483a-a092-d06ea46dfb8z/resourceGroups/rgContoso/providers/Microsoft.Storage/storageAccounts/sacontoso
Active Key Name     : key1
Auto Regenerate Key : True
Regeneration Period : 30.00:00:00
Enabled             : True
Created             : 11/19/2018 11:54:47 PM
Updated             : 11/19/2018 11:54:47 PM
Tags                :

共享访问签名令牌

也可以要求 Key Vault 生成共享访问签名令牌。 共享访问签名对存储帐户中的资源提供委托访问。 可以授予客户端访问存储帐户中的资源的权限,而无需共享帐户密钥。 使用共享访问签名可以安全共享存储资源,而不会透露帐户密钥。

本部分所述的命令将完成以下操作:

  • 设置帐户共享访问签名定义。
  • 在保管库中设置 Key Vault 托管的存储共享访问签名定义。 该定义包含创建的共享访问签名令牌的模板 URI。 该定义使用共享访问签名类型 account,有效期为 N 天。
  • 验证共享访问签名是否已作为机密保存在 Key Vault 中。

设置变量

首先,通过以下步骤设置 PowerShell cmdlet 使用的变量。 请务必更新 YourStorageAccountName 和 YourKeyVaultName 占位符<><>。

我们还将使用 Azure PowerShell New-AzStorageContext cmdlet 来获取 Azure 存储帐户的上下文。

$storageAccountName = <YourStorageAccountName>
$keyVaultName = <YourKeyVaultName>

$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -Protocol Https -StorageAccountKey Key1 #(or "Primary" for Classic Storage Account)

定义共享访问签名定义模板

Key Vault 使用 SAS 定义模板为客户端应用程序生成令牌。

Key Vault 的 SAS 定义模板中所需的帐户 SAS 参数

SAS 查询参数 说明
SignedVersion (sv) 必需。 指定用于为使用此帐户 SAS 发出的请求授权的已签名存储服务版本。 必须设置为版本 2015-04-05 或更高版本。 Key Vault 支持不高于 2018-03-28 的版本
SignedServices (ss) 必需。 指定可使用帐户 SAS 访问的已签名服务。 可能的值包括:

- Blob (b)
- 队列 (q)
- 表 (t)
- 文件 (f)

可以将值组合在一起,以提供对多个服务的访问权限。 例如,ss=bf 指定对 Blob 和文件终结点的访问权限。
SignedResourceTypes (srt) 必需。 指定可使用帐户 SAS 访问的已签名资源类型。

- 服务 (s):对服务级 API(例如,获取/设置服务属性、获取服务统计信息、列出容器/队列/表/共享)的访问权限
- 容器 (c):对容器级 API(例如,创建/删除容器、创建/删除队列、创建/删除表、创建/删除共享、列出 Blob/文件和目录)的访问权限
- 对象 (o):对 Blob、队列消息、表实体和文件的对象级 API(例如,放置 Blob、查询实体、获取消息、创建文件等)的访问权限

可以将值组合在一起,以提供对多个资源类型的访问权限。 例如,srt=sc 指定对服务和容器资源的访问权限。
SignedPermission (sp) 必需。 指定帐户 SAS 的已签名权限。 仅当权限与指定的已签名资源类型匹配时,权限才有效;否则会忽略它们。

- 读取 (r):对所有已签名的资源类型(服务、容器和对象)有效。 允许对指定的资源类型的读取权限。
- 写入 (w):对所有已签名的资源类型(服务、容器和对象)有效。 允许对指定的资源类型的写入权限。
- 删除 (d):对容器和对象资源类型有效,但队列消息除外。
- 永久删除 (y):仅对 Blob 的对象资源类型有效。
- 列出 (l):仅对服务和容器资源类型有效。
- 添加 (a):仅对以下对象资源类型有效:队列消息、表实体和追加 Blob。
- 创建 (c):仅对以下对象资源类型有效:Blob 和文件。 用户可以创建新的 Blob 或文件,但不能覆盖现有的 Blob 或文件。
- 更新 (u):仅对以下对象资源类型有效:队列消息和表实体。
- 处理 (p):仅对以下对象资源类型有效:队列消息。
- 标记 (t):仅对以下对象资源类型有效:Blob。 允许 Blob 标记操作。
- 筛选 (f):仅对以下对象资源类型有效:Blob。 允许按 Blob 标记进行筛选。
- 设置不可变性策略 (i):仅对以下对象资源类型有效:Blob。 允许对 Blob 设置/删除不可变性策略和法定保留。
SignedProtocol (spr) 可选。 指定允许用于使用帐户 SAS 发出的请求的协议。 可能的值为“HTTPS 和 HTTP”(https,http) 或“仅 HTTPS”(https)。 默认值是 https,http

请注意,“仅限 HTTP”是不允许的值。

SAS 定义模板示例:

$sasTemplate="sv=2018-03-28&ss=bfqt&srt=sco&sp=rw&spr=https"

有关帐户 SAS 的详细信息,请参阅:创建帐户 SAS

注意

Key Vault 会忽略“已签名到期时间”、“已签名开始时间”等生命周期参数以及在 2018-03-28 版本之后引入的参数

在 Key Vault 中设置共享访问签名定义

使用 Azure PowerShell Set-AzKeyVaultManagedStorageSasDefinition cmdlet 创建共享访问签名定义。 可将所选的名称提供给 -Name 参数。

Set-AzKeyVaultManagedStorageSasDefinition -AccountName $storageAccountName -VaultName $keyVaultName -Name <YourSASDefinitionName> -TemplateUri $sasTemplate -SasType 'account' -ValidityPeriod ([System.Timespan]::FromDays(1))

验证共享访问签名定义

可以使用 Azure PowerShell Get-AzKeyVaultSecret cmdlet 验证共享访问签名定义是否已存储在 Key Vault 中。

首先,在 Key Vault 中找到共享访问签名定义。

Get-AzKeyVaultSecret -VaultName <YourKeyVaultName>

对应于 SAS 定义的机密包含以下属性:

Vault Name   : <YourKeyVaultName>
Name         : <SecretName>
...
Content Type : application/vnd.ms-sastoken-storage
Tags         :

现在可以将 Get-AzKeyVaultSecret cmdlet 与 VaultNameName 参数一起使用,以便查看该机密的内容。

$secret = Get-AzKeyVaultSecret -VaultName <YourKeyVaultName> -Name <SecretName>
$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue)
try {
   $secretValueText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
} finally {
   [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
}
Write-Output $secretValueText

此命令的输出将显示 SAS 定义字符串。

后续步骤