1

我正在尝试使用服务原则从 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 访问控制,App ID 和机密是属于批处理帐户所有者的。任何想法接下来要尝试什么?

4

3 回答 3

2

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

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

样品在这里

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

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

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

  1. 针对密钥保管库获取服务主体身份验证以获取名称和密钥
  2. 使用名称和密钥创建凭据
于 2017-11-02T15:34:00.930 回答
0

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

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

于 2017-11-02T16:17:18.040 回答
0

我碰巧遇到了同样的问题,我没有使用 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();
            }
        });
    });
};
于 2020-02-14T20:50:48.933 回答