Доступ к пакету Azure из функции Azure

Я пытаюсь использовать принцип обслуживания для доступа к пулу пакетов из функции Azure и сталкиваюсь с проблемами аутентификации, которые мне не понятны. Первоначальный вход в систему с принципом обслуживания работает нормально, но затем использование учетных данных для доступа к пулу пакетов возвращает 401.

Ниже приведена сокращенная версия моего кода с комментариями по ключевым моментам.

module.exports.dispatch = function (context) {

    MsRest.loginWithServicePrincipalSecret('AppId', 'Secret', 'TennantId', function(err, credentials){

        if (err) throw err;
        // This works as it prints the credentials
        context.log(credentials);

        var batch_client = new batch.ServiceClient(credentials, accountUrl);

        batch_client.pool.get('mycluster', function(error, result){

            if(error === null)
            {
                context.log('Accessed pool');
                context.log(result);
            }
            else
            {
                //Request to batch service returns a 401
                if(error.statusCode === 404)
                {
                    context.log('Pool not found yet returned 404...');

                }
                else
                {
                    context.log('Error occurred while retrieving pool data');
                    context.log(error);
                }

                //'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly.
                context.res = { body: error.body.message.value };
                context.done();
            }
        });
    });
};

Как первоначальный вход в систему с принципом службы может работать без проблем, но тогда возвращаемые учетные данные не смогут получить доступ к пулу пакетов?

Фактическая ошибка говорит о проверке заголовка auth по запросу, который я вижу, а заголовок Authorization даже отсутствует.

Я трижды проверил контроль доступа к Active Directory для пакетной учетной записи, идентификатор приложения и секретная информация принадлежат владельцу пакетной учетной записи. Есть идеи, что попробовать дальше?

2 ответа

Решение

Учетные данные, ожидаемые клиентом Azure Batch npm, - это не учетные данные / токен Azure Active Directory, а ключи учетной записи пакета. Вы можете получить список ключей с помощью интерфейса командной строки Azure, выполнив следующую команду:

az batch account keys list -g "<resource-group-name>" -n "<batch-account-name>"

образец здесь

Затем вы можете создать параметр credentials с этими ключами:

var credentials = new batch.SharedKeyCredentials('your-account-name', 'your-account-key');

Вы по-прежнему можете привлекать сюда руководителя службы, если хотите сохранить свои пакетные ключи в чем-то вроде Key Vault, но тогда ваш код будет:

  1. Получить сервис-принципал аутентификации для хранилища ключей, чтобы получить имя и ключ
  2. Используйте имя и ключ для создания учетных данных

Нельзя использовать тот же токен OAuth, который был возвращен из конечной точки управления ресурсами Azure вместе с пакетной службой. Предполагая, что у участника службы есть правильные разрешения RBAC, выполните аутентификацию с помощью конечной точки пакета Azure: https://batch.core.windows.net/ вместо этого (при условии, что вы используете Public Azure).

Вам не нужно получать учетные данные общего ключа для учетной записи Batch, вместо этого следует использовать учетные данные через AAD, если вы используете субъект службы AAD.

Мне довелось столкнуться с этой же проблемой, и у меня не было возможности использовать SharedKeyCredentials, поэтому я хотел поделиться своим решением на случай, если кто-то найдет его полезным.

Как упоминает fpark, нам нужно получить токен OAuth для использования с пакетной службой вместо стандартного управления ресурсами Azure. Ниже представлен исходный код, опубликованный Марком, с небольшими изменениями, необходимыми для его работы с пакетной службой:

module.exports.dispatch = function (context) {

    let authOptions = {tokenAudience: 'batch'};

    MsRest.loginWithServicePrincipalSecret('AppId', 'Secret', 'TennantId', authOptions, function(err, credentials){

        if (err) throw err;
        // This works as it prints the credentials
        context.log(credentials);

        var batch_client = new batch.ServiceClient(credentials, accountUrl);

        batch_client.pool.get('mycluster', function(error, result){

            if(error === null)
            {
                context.log('Accessed pool');
                context.log(result);
            }
            else
            {
                //Request to batch service returns a 401
                if(error.statusCode === 404)
                {
                    context.log('Pool not found yet returned 404...');

                }
                else
                {
                    context.log('Error occurred while retrieving pool data');
                    context.log(error);
                }

                //'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly.
                context.res = { body: error.body.message.value };
                context.done();
            }
        });
    });
};
Другие вопросы по тегам