简体   繁体   English

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

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

I'm having issues getting a secret from azure keyvault using the azure-keyvault package from a node application running on a linux vm on azure.我在从 azure 上的 linux vm 上运行的节点应用程序中使用 azure-keyvault 包从 azure keyvault 获取机密时遇到问题。

I am using the following code:我正在使用以下代码:

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...
});

I am getting a 401 response when calling getSecret.调用 getSecret 时收到 401 响应。 There are permissions set to the machine on the keyvault and MSI.在密钥库和 MSI 上为计算机设置了权限。 In the error I get there doesn't seem to be any header of authentication or a token, although I do see a header which looks like an authentication header on the response.在我得到的错误中,似乎没有任何身份验证标头或令牌,尽管我确实在响应中看到了一个看起来像身份验证标头的标头。

Is there anything I am missing in my implementation?我的实现中是否缺少什么?

EDIT: It looks like the example I've shared here would have worked if I would use编辑:看起来我在这里分享的例子如果我会使用

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

instead of calling it with no params.而不是在没有参数的情况下调用它。

In your keyvault, make sure you have added the service principal(created automatically by enabling the MSI) in the Access policies with correct secret permission.在您的密钥库中,确保您已在Access policies具有正确机密权限的服务主体(通过启用 MSI 自动创建)。 Then try to click Click to show advanced access policies -> choose the Enable access to Azure Virtual Machines for deployment option-> Save.然后尝试单击“ Click to show advanced access policies -> 选择“ Enable access to Azure Virtual Machines for deployment选项->“保存”。

Here is a code sample, you could check the part of retrieving a secret value.这是一个代码示例,您可以检查检索秘密值的部分。

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);    
    // })
});

For more details, you could refer to :Set and retrieve a secret from Azure Key Vault using a Node Web App .有关更多详细信息,您可以参考:使用 Node Web App 从 Azure Key Vault 设置和检索机密

This has now been simplified in the new @azure/keyvault-secrets package where the SecretClient can take the DefaultAzureCredential from the @azure/identity package which in turn is smart enough to use the MSI details when run in your VM as well as the developer credentials like VS Code or Azure CLI when in your local dev environment.这在新的@azure/keyvault-secrets包中得到了简化,其中SecretClient可以从@azure/identity包中获取DefaultAzureCredential ,这反过来又足够聪明,可以在 VM 和开发人员中运行时使用 MSI 详细信息在本地开发环境中使用 VS Code 或 Azure CLI 等凭据。 You can learn more about this in the readme for @azure/identity您可以在@azure/identity自述文件中了解更多相关信息

With this, your code would be simplified to有了这个,您的代码将被简化为

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;
}

To move your application from the older azure-keyvault package which is now deprecated, you can see the migration guide to the new @azure/keyvault-secrets要将您的应用程序从现在已弃用的旧版azure-keyvault包中移动,您可以查看新版 @azure/keyvault-secrets迁移指南

You can use read-azure-secrets which will retrieve all secrets from the azure key vault.您可以使用read-azure-secrets来检索 Azure Key Vault 中的所有机密。

For example例如

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