Получение секрета из лазурного хранилища ключей с узлом из виртуальной машины Linux с MSI

У меня возникают проблемы с получением секрета из хранилища ключей Azure с помощью пакета azure-keyvault из приложения узла, работающего на виртуальной машине Linux в Azure.

Я использую следующий код:

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

Я получаю ответ 401 при вызове getSecret. В хранилище ключей и MSI установлены разрешения для машины. В ошибке, которую я получаю, похоже, нет заголовка аутентификации или токена, хотя я вижу заголовок, который выглядит как заголовок аутентификации в ответе.

Есть ли что-то, что мне не хватает в моей реализации?

Обновлено: Похоже, что пример, которым я поделился здесь, сработал бы, если бы я использовал

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

вместо того, чтобы вызывать его без параметров.

Я запутался. Где вы запрашиваете токен? Вы должны увидеть свой токен в заголовке ответа от вашего https-запроса. Также вам нужно использовать обратные вызовы.

user5780947 08.04.2019 20:05

@ Rthomas529 Rthomas529 Я пытаюсь использовать пакет azure-keyvault... поэтому часть информации скрыта от меня. Вы предлагаете просто использовать обычный API с простыми HTTP-запросами?

Mithir 10.04.2019 08:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
716
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

В хранилище ключей убедитесь, что вы добавили субъект-службу (созданную автоматически при включении MSI) в Access policies с правильным секретным разрешением. Затем попробуйте нажать 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.info("Secret id: '" + kvSecretBundle.id + "'.");
            return keyVaultClient.getSecret(kvSecretBundle.id, {});
        })
        .then( (bundle) => {
            console.info("Successfully retrieved 'test-secret'");
            console.info(bundle);
        })
        .catch( (err) => {
            console.info(err);
        });

    // Below code demonstrates how to retrieve a secret value

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

Для получения более подробной информации вы можете обратиться к: Установка и получение секрета из Azure Key Vault с помощью веб-приложения Node..

Я заметил, что вы используете loginWithAppServiceMSI в своем примере, но у меня нет AppService, у меня есть обычная виртуальная машина, разве я не должен использовать loginWithVmMSI?

Mithir 10.04.2019 08:34

@Mithir Да, я думаю, в вашем случае вам следует использовать loginWithVmMSI. Кстати, вы сначала проверили свои разрешения?

Joy Wang 10.04.2019 09:00

Я только что реализовал получение секрета с помощью простых http-запросов, и это сработало. Сначала я получаю токен, а затем получаю секрет с заголовком авторизации, в котором есть данные о токене, поэтому разрешения в порядке. Я все еще предпочитаю использовать пакет, но я не уверен, чего не хватает...

Mithir 10.04.2019 10:00

@Mithir Не могли бы вы последовать образцу, чтобы попробовать? Независимо от того, используете ли вы msi службы приложений или vm, логика должна быть одинаковой.

Joy Wang 10.04.2019 10:06

Хорошо, большое спасибо... кажется, я пропустил ресурсную часть в своем примере... Большое спасибо!

Mithir 10.04.2019 13:18

Вы можете использовать чтение лазурных секретов, который извлечет все секреты из хранилища ключей Azure.

Например

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

}

loadKeyVaultValues();

Теперь это было упрощено в новом пакете @azure/keyvault-secrets, где SecretClient может взять DefaultAzureCredential из пакета @azure/identity, который, в свою очередь, достаточно умен, чтобы использовать данные 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

Другие вопросы по теме