繁体   English   中英

从带有 MSI 的 linux vm 使用节点从 azure keyvault 获取秘密

[英]Getting a secret from azure keyvault with node from a linux vm with MSI

我在从 azure 上的 linux vm 上运行的节点应用程序中使用 azure-keyvault 包从 azure keyvault 获取机密时遇到问题。

我正在使用以下代码:

import * as KeyVault from 'azure-keyvault';
import * as msRestAzure from 'ms-rest-azure'

function getKeyVaultCredentials(){
    return msRestAzure.loginWithVmMSI();
}

function getKeyVaultSecret(credentials) {
    let keyVaultClient = new KeyVault.KeyVaultClient(credentials,null);
    return keyVaultClient.getSecret("my keyvault url here", 'my keyvault secret name here', "", null,null);
}

getKeyVaultCredentials().then(
    getKeyVaultSecret
).then(function (secret){
    //not getting here....
}).catch(function (err) {
    //...error handling...
});

调用 getSecret 时收到 401 响应。 在密钥库和 MSI 上为计算机设置了权限。 在我得到的错误中,似乎没有任何身份验证标头或令牌,尽管我确实在响应中看到了一个看起来像身份验证标头的标头。

我的实现中是否缺少什么?

编辑:看起来我在这里分享的例子如果我会使用

msRestAzure.loginWithVmMSI({resource: 'https://vault.azure.net' });

而不是在没有参数的情况下调用它。

在您的密钥库中,确保您已在Access policies具有正确机密权限的服务主体(通过启用 MSI 自动创建)。 然后尝试单击“ Click to show advanced access policies -> 选择“ Enable access to Azure Virtual Machines for deployment选项->“保存”。

这是一个代码示例,您可以检查检索秘密值的部分。

var http = require('http');
const KeyVault = require('azure-keyvault');
const msRestAzure = require('ms-rest-azure');


var server = http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
});

// The ms-rest-azure library allows us to login with MSI by providing the resource name. In this case the resource is Key Vault.
// For public regions the resource name is Key Vault
msRestAzure.loginWithAppServiceMSI({resource: 'https://vault.azure.net'}).then( (credentials) => {
    const keyVaultClient = new KeyVault.KeyVaultClient(credentials);

    var vaultUri = "https://" + "<YourVaultName>" + ".vault.azure.net/";

    // We're setting the Secret value here and retrieving the secret value
    keyVaultClient.setSecret(vaultUri, 'my-secret', 'test-secret-value', {})
        .then( (kvSecretBundle, httpReq, httpResponse) => {
            console.log("Secret id: '" + kvSecretBundle.id + "'.");
            return keyVaultClient.getSecret(kvSecretBundle.id, {});
        })
        .then( (bundle) => {
            console.log("Successfully retrieved 'test-secret'");
            console.log(bundle);
        })
        .catch( (err) => {
            console.log(err);
        });

    // Below code demonstrates how to retrieve a secret value

    // keyVaultClient.getSecret(vaultUri, "AppSecret", "").then(function(response){
    //     console.log(response);    
    // })
});

有关更多详细信息,您可以参考:使用 Node Web App 从 Azure Key Vault 设置和检索机密

这在新的@azure/keyvault-secrets包中得到了简化,其中SecretClient可以从@azure/identity包中获取DefaultAzureCredential ,这反过来又足够聪明,可以在 VM 和开发人员中运行时使用 MSI 详细信息在本地开发环境中使用 VS Code 或 Azure CLI 等凭据。 您可以在@azure/identity自述文件中了解更多相关信息

有了这个,您的代码将被简化为

const { SecretClient } = require("@azure/keyvault-secrets");
const { DefaultAzureCredential } = require("@azure/identity");

async function getValue(secretName, secretVersion) {
  const credential = new DefaultAzureCredential();
  const client = new SecretClient(KEY_VAULT_URI, credential);
  const secret = await client.getSecret(secretName);
  return secret.value;
}

要将您的应用程序从现在已弃用的旧版azure-keyvault包中移动,您可以查看新版 @azure/keyvault-secrets迁移指南

您可以使用read-azure-secrets来检索 Azure Key Vault 中的所有机密。

例如

let secretClient = require('read-azure-secrets');

async function loadKeyVaultValues() {

    let applicationID = '';
    let applicationSecret = '';
    let vaultURL = 'https://<your-key-vault-name>.vault.azure.net/';
    let secrets = await secretClient.getSecrets(applicationID, applicationSecret, vaultURL);

    secrets.forEach(secret => {
        console.log(secret);
    });

}

loadKeyVaultValues();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM