从 Azure 函数访问 Azure Batch

Access Azure Batch from an Azure Function

我正在尝试使用服务原则从 Azure 函数访问批处理池,并 运行 解决我不了解的身份验证问题。使用 Service Principle 的初始登录工作正常,但随后使用凭据访问批处理池 returns a 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();
            }
        });
    });
};

怎么用服务原理的初始登录没问题,然后凭据returns就不能访问批处理池了?

实际错误说要检查请求的授权 header,我可以看到,授权 header 甚至不存在。

我已经对批处理帐户的 Active Directory 访问控制进行了三次检查,App ID 和密码属于批处理帐户的所有者。知道接下来要尝试什么吗?

Azure Batch npm 客户端需要的凭据不是 Azure Active Directory credentials/token,而是批处理帐户的密钥。您可以使用 Azure CLI 通过如下命令列出您的密钥:

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

sample here

然后您可以使用这些密钥创建凭据参数:

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

如果您想将批处理密钥存储在 Key Vault 之类的东西中,您仍然可以在此处涉及服务委托人,但是您的代码将是:

  1. 获取针对密钥保管库的服务主体身份验证以获取名称和密钥
  2. 使用名称和密钥创建凭据

您不能对 Batch 使用从 Azure 资源管理终结点返回的相同 OAuth 令牌。假设您的服务主体具有正确的 RBAC 权限,则使用 Azure Batch 端点进行身份验证:https://batch.core.windows.net/(假设您使用的是 Public Azure)。

您不需要获取 Batch 帐户的共享密钥凭据,如果您使用的是 AAD 服务主体,则应使用通过 AAD 提供的凭据。

我碰巧 运行 遇到了同样的问题,但我没有使用 SharedKeyCredentials 的选项,所以我想分享我的解决方案,以防其他人觉得它有用。

正如 fpark 所提到的,我们需要获取一个 OAuth 令牌以与 Batch 一起使用,而不是默认的 Azure 资源管理。下面是 Mark 发布的原始代码,稍作修改后即可与 Batch 一起使用:

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