首页 > 解决方案 > 在 C# .Net 中使用 MSI 访问 Azure Key Vault

问题描述

由于我是 Azure 的新手,所以这个问题可能很愚蠢。我正在尝试构建一个服务来配置和管理一个虚拟机集群。出于安全考虑,我不想在每个集群上放置一些敏感数据。所以我决定为每个集群配置一个 Azure Key Vault 来存储这些数据,并创建一个 MSI(托管标识)并分派到集群的每个节点,以便 vm 可以访问密钥库以获取机密。

在服务端,我需要配置 vms、key Vault 和 MSI。将 MSI 分配给每个 VM,同时将正确的角色授予 MSI 以访问 AKV。这是我的问题:

  1. 系统 MSI 与用户 MSI,因为集群将有多个节点,为了减少配置整个集群的延迟,用户 msi 可能是一个更好的主意,因为我们可以配置一个 MSI 并授予一次访问权限。对于系统分配的 MSI,我们需要为每个身份授予访问权限。但缺点是,我们必须在删除整个集群时删除 MSI。你对此有何看法?
  2. 愚蠢的问题,如何预配 MSI、Azure Key Vault 并授予访问权限。你能给我看一些代码示例吗?我试图在网上找到公共 API 文档和教程,但失败了。

标签: azureazure-active-directoryazure-keyvaultazure-managed-identityazure-rbac

解决方案


1. 系统分配的托管标识和用户分配的托管标识有什么区别?

根据我的研究,系统分配的托管标识直接在 Azure 服务实例上启用。系统分配标识的生命周期直接与启用它的 Azure 服务实例相关联。如果实例被删除,Azure 会自动清理 Azure AD 中的凭据和标识。

但是,用户分配的托管标识创建为独立的 Azure 资源。创建标识后,可以将标识分配给一个或多个 Azure 服务实例。用户分配标识的生命周期与其分配到的 Azure 服务实例的生命周期分开管理。

更多详细信息,请参阅文档

2. 如何配置 MSI、Azure Key Vault 并授予访问权限

预配用户分配的托管标识

根据我的研究,如果我们想提供用户分配的托管标识,我们可以使用Azure REST APIAzure PowershellAzure CLI

例如

Azure CLI

az login
az identity create -g <RESOURCE GROUP> -n <USER ASSIGNED IDENTITY NAME>

Azure REST API 使用 Azure CLI 获取访问令牌

az login
az account get-access-token

湾。调用其余 api

curl 'https://management.azure.com/subscriptions/<SUBSCRIPTION ID>/resourceGroup
s/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>?api-version=2015-08-31-preview' -X PUT -d '{"loc
ation": "<LOCATION>"}' -H "Content-Type: application/json" -H "Authorization: Bearer <ACCESS TOKEN>"

预配 Azure Key Vault 并授予访问权限

根据我的研究,如果我们想实现它,如果我们想提供用户分配的托管标识,我们可以使用Azure REST APIAzure PowershellAzure CLI和 sdk(例如 .net)。更多详细信息,请参阅文档

例如

Azure 休息 API

一种。使用 Azure CLI 获取访问令牌

az login
az account get-access-token

湾。调用其余 api

PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}?api-version=2018-02-14
Header :
   Content-Type: application/json
   Authorization: Bearer <ACCESS TOKEN>
Body

  {
  "location": "westus",
  "properties": {
    "tenantId": "<your tenant id>",
    "sku": {
      "family": "A",
      "name": "standard"
    },
    "accessPolicies": [
      {
        "tenantId": "<your tenant id>",
        "objectId": "<the object id of the MSI>",
        "permissions": {
          "keys": [
            "encrypt",
            "decrypt",
            "wrapKey",
            "unwrapKey",
            "sign",
            "verify",
            "get",
            "list",
            "create",
            "update",
            "import",
            "delete",
            "backup",
            "restore",
            "recover",
            "purge"
          ],
          "secrets": [
            "get",
            "list",
            "set",
            "delete",
            "backup",
            "restore",
            "recover",
            "purge"
          ],
          "certificates": [
            "get",
            "list",
            "delete",
            "create",
            "import",
            "update",
            "managecontacts",
            "getissuers",
            "listissuers",
            "setissuers",
            "deleteissuers",
            "manageissuers",
            "recover",
            "purge"
          ]
        }
      }
    ],
    "enabledForDeployment": true,
    "enabledForDiskEncryption": true,
    "enabledForTemplateDeployment": true
  }
}

.Net SDK

一种。使用 Azure CLI 创建服务主体

az login
az ad sp create-for-rbac -n "MyApp" --role contributor --sdk-auth

湾。代码。有关详细信息,请参阅示例

// please install package  Microsoft.Azure.Management.Fluent
var credentials = SdkContext.AzureCredentialsFactory
    .FromServicePrincipal(<the sp app id>,
    <the sp password>,
    tenantId, 
    AzureEnvironment.AzureGlobalCloud);
var azure = Microsoft.Azure.Management.Fluent.Azure
    .Configure()
    .Authenticate(credentials)
    .WithSubscription ("<your subscription id>");
var vault =await azure.Vaults.Define("")
                       .WithRegion(Region.AsiaSouthEast)
                       .WithExistingResourceGroup("groupname")
                       .DefineAccessPolicy()
                              .ForObjectId("the object id of msi")
                              .AllowCertificateAllPermissions()
                              .AllowKeyAllPermissions()
                              .AllowSecretAllPermissions()
                              .Attach()
                       .WithDeploymentEnabled()
                       .WithDiskEncryptionEnabled()
                       .WithTemplateDeploymentEnabled()
                       .WithSku(Microsoft.Azure.Management.KeyVault.Fluent.Models.SkuName.Standard)
                       .CreateAsync()

推荐阅读