教程:使用 Linux VM 系统分配的托管标识通过访问密钥访问 Azure 存储

Azure 资源的托管标识是 Microsoft Entra ID 的一项功能。 支持 Azure 资源的托管标识的每个 Azure 服务都受其自己的时间线限制。 在开始之前,请务必查看资源的托管标识的可用性状态以及已知问题

本教程介绍如何使用 Linux 虚拟机 (VM) 的系统分配托管标识来检索存储帐户访问密钥。 可以像平常在执行存储操作时一样使用存储访问密钥,例如使用存储 SDK 时。 本教程使用 Azure CLI 上传和下载 blob。 将了解如何执行以下操作:

  • 授予 VM 对资源管理器中存储帐户访问密钥的访问权限
  • 使用 VM 的标识获取一个访问令牌,并使用它从资源管理器检索存储访问密钥

必备条件

创建存储帐户

如果你没有要在本教程中使用的现有存储帐户,则需要创建一个。 也可以跳过此步骤,并向 VM 的系统分配的托管标识授予对现有存储帐户密钥的访问权限。

  1. 选择 Azure 门户左上角的“+/创建新服务”按钮。

  2. 选择“存储”,然后选择“存储帐户”,此时会显示新的“创建存储帐户”面板。

  3. 输入存储帐户的“名称”。

  4. “部署模型”和“帐户类型”应分别设置为“资源管理器”和“通用” 。

  5. 确保“订阅”和“资源组”与上一步中创建 VM 时指定的名称匹配。

  6. 选择创建

    屏幕截图显示如何新建存储帐户。

在存储帐户中创建 Blob 容器

稍后我们会将文件上传并下载到新存储帐户。 由于文件需要 blob 存储,我们需要创建用于存储文件的 blob 容器。

  1. 导航回新创建的存储帐户。

  2. 在“Blob 服务”下选择左侧的“容器”链接。

  3. 选择页面顶部的“+ 容器”,此时会滑出一个“新建容器”面板。

  4. 为容器指定名称,选择访问级别,然后选择“确定”。 在本教程中的后面部分将使用所指定的名称。

    屏幕截图显示如何创建存储容器。

授权 VM 的系统分配的托管标识使用存储帐户访问密钥

Azure 存储原本不支持 Microsoft Entra 身份验证。 但是,可以使用 VM 的系统分配的托管标识从资源管理器检索存储 SAS,然后使用 SAS 来访问存储。 在此步骤中,将向 VM 的系统分配的托管标识授予对存储帐户 SAS 的访问权限。 通过向包含存储帐户的资源组范围中的托管标识分配存储帐户参与者角色来授予访问权限。

有关详细步骤,请参阅使用 Azure 门户分配 Azure 角色

注意

有关可用于授予存储权限的各种角色的信息,请查看使用 Microsoft Entra ID 对 Blob 和队列授予访问权限

使用 VM 标识获取访问令牌,并使用它调用 Azure 资源管理器

在本教程的剩余部分,我们从先前创建的 VM 入手。

若要完成这些步骤,需要使用 SSH 客户端。 如果使用的是 Windows,可以在适用于 Linux 的 Windows 子系统中使用 SSH 客户端。 如果需要有关配置 SSH 客户端密钥的帮助,请参阅如何在 Azure 上将 SSH 密钥与 Windows 配合使用如何创建和使用适用于 Azure 中 Linux VM 的 SSH 公钥和私钥对

  1. 在 Azure 门户中,导航到“虚拟机”,选择你的 Linux 虚拟机,然后在“概述”页中选择顶部的“连接”。 复制用于连接到 VM 的字符串。

  2. 使用 SSH 客户端连接到 VM。

  3. 接下来,你需要输入创建 Linux VM 时添加的“密码”

  4. 使用 CURL 获取 Azure 资源管理器的访问令牌。

    下面是用于获取访问令牌的 CURL 请求和响应:

    curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.chinacloudapi.cn%2F' -H Metadata:true
    

    注意

    在上面的请求中,“resource”参数的值必须与 Microsoft Entra ID 预期的值完全一致。 如果使用 Azure 资源管理器资源 ID,必须在 URI 的结尾添加斜线。 在下面的响应中,为简洁起见,已缩短了 access_token 元素。

    {
      "access_token": "eyJ0eXAiOiJ...",
      "refresh_token": "",
      "expires_in": "3599",
      "expires_on": "1504130527",
      "not_before": "1504126627",
      "resource": "https://management.chinacloudapi.cn",
      "token_type": "Bearer"
    }
    

从 Azure 资源管理器中获取存储帐户访问密钥,以便调用存储

现在,使用在上一部分中检索到的访问令牌通过 CURL 调用资源管理器,以便检索存储访问密钥。 获得存储访问密钥后,便可以调用存储上传/下载操作。 请务必将 <SUBSCRIPTION ID><RESOURCE GROUP><STORAGE ACCOUNT NAME> 参数值替换为你自己的值。 将 <ACCESS TOKEN> 值替换为前面检索到的访问令牌:

curl https://management.chinacloudapi.cn/subscriptions/<SUBSCRIPTION ID>/resourceGroups/<RESOURCE GROUP>/providers/Microsoft.Storage/storageAccounts/<STORAGE ACCOUNT NAME>/listKeys?api-version=2016-12-01 --request POST -d "" -H "Authorization: Bearer <ACCESS TOKEN>" 

注意

上述 URL 中的文本区分大小写,因此如果对资源组使用了大小写格式,请务必在 URL 中相应地体现出来。 另外,请注意,这是 POST 请求而不是 GET 请求,请务必使用 -d 来传递一个值,以捕获长度限制,此值可以为 NULL。

CURL 响应将提供一个密钥列表:

{"keys":[{"keyName":"key1","permissions":"Full","value":"iqDPNt..."},{"keyName":"key2","permissions":"Full","value":"U+uI0B..."}]} 

创建要上传到 blob 存储容器的示例 blob 文件。 在 Linux VM 上,可使用以下命令执行该操作。

echo "This is a test file." > test.txt

接下来,运行 CLI az storage 命令并使用存储访问密钥进行身份验证,然后将文件上传到 blob 容器。 对于此步骤,需要在 VM 上安装最新的 Azure CLI(如果尚未安装)。

az storage blob upload -c <CONTAINER NAME> -n test.txt -f test.txt --account-name <STORAGE ACCOUNT NAME> --account-key <STORAGE ACCOUNT KEY>

响应:

Finished[#############################################################]  100.0000%
{
  "etag": "\"0x8D4F9929765C139\"",
  "lastModified": "2017-09-12T03:58:56+00:00"
}

此外,可以使用 Azure CLI 下载文件,并使用存储访问密钥对其进行身份验证。

请求:

az storage blob download -c <CONTAINER NAME> -n test.txt -f test-download.txt --account-name <STORAGE ACCOUNT NAME> --account-key <STORAGE ACCOUNT KEY>

响应:

{
  "content": null,
  "metadata": {},
  "name": "test.txt",
  "properties": {
    "appendBlobCommittedBlockCount": null,
    "blobType": "BlockBlob",
    "contentLength": 21,
    "contentRange": "bytes 0-20/21",
    "contentSettings": {
      "cacheControl": null,
      "contentDisposition": null,
      "contentEncoding": null,
      "contentLanguage": null,
      "contentMd5": "LSghAvpnElYyfUdn7CO8aw==",
      "contentType": "text/plain"
    },
    "copy": {
      "completionTime": null,
      "id": null,
      "progress": null,
      "source": null,
      "status": null,
      "statusDescription": null
    },
    "etag": "\"0x8D5067F30D0C283\"",
    "lastModified": "2017-09-28T14:42:49+00:00",
    "lease": {
      "duration": null,
      "state": "available",
      "status": "unlocked"
    },
    "pageBlobSequenceNumber": null,
    "serverEncrypted": false
  },
  "snapshot": null
}

后续步骤

在本教程中,你已学习了如何使用 Linux VM 系统分配的托管标识通过访问密钥来访问 Azure 存储。 若要详细了解 Azure 存储访问密钥,请参阅: