使用 Node Js 的 Azure 身份验证 DefaultAzureCredential

Azure Identity Authentication DefaultAzureCredential with Node Js

我试图在 Node js 中使用 @azure/identity 对 Azure DefaultAzureCredential 进行身份验证,以获取 Azure API 管理服务的报告。

我做过的事情:

  1. 从 Azure 门户创建了一个 API 管理服务

  2. 已使用 Azure AD 注册应用程序并使用 this 文档创建服务主体。

  3. 我已正确配置环境变量以使用 this 文档中提到的 DefaultAzureCredential。

    AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION,

但是身份验证失败,我无法生成凭据。当我安慰 new DefaultAzureCredential(); 回复时,它说 UnavailableMessage: 'DefaultAzureCredential => failed to retrieve a token from the included credentials',

require("dotenv").config();
const { DefaultAzureCredential } = require("@azure/identity");
const { ApiManagementClient } = require("@azure/arm-apimanagement");

if (!process.env.AZURE_TENANT_ID) throw Error("AZURE_TENANT_ID is missing from environment variables.");
if (!process.env.AZURE_CLIENT_ID) throw Error("AZURE_CLIENT_ID is missing from environment variables.");
if (!process.env.AZURE_CLIENT_SECRET) throw Error("AZURE_CLIENT_SECRET is missing from environment variables.");
if (!process.env.AZURE_RESOURCE_GROUP) throw Error("AZURE_RESOURCE_GROUP is missing from environment variables.");
if (!process.env.AZURE_SERVICE_NAME) throw Error("AZURE_SERVICE_NAME is missing from environment variables.");
if (!process.env.AZURE_SUBSCRIPTION) throw Error("AZURE_SUBSCRIPTION is missing from environment variables.");

const subscriptionId = process.env.AZURE_SUBSCRIPTION;

const credentials = new DefaultAzureCredential();

console.log(credentials);

我遇到了这个错误,

DefaultAzureCredential {
  UnavailableMessage: 'DefaultAzureCredential => failed to retrieve a token from the included credentials',
  _sources: [
    EnvironmentCredential { _credential: [ClientSecretCredential] },
    ManagedIdentityCredential {
      isEndpointUnavailable: null,
      clientId: 'c8xxxxxxxx5ac8',
      identityClient: [IdentityClient]
    },
    AzureCliCredential {},
    VisualStudioCodeCredential {
      cloudName: 'AzureCloud',
      identityClient: [IdentityClient],
      tenantId: 'common'
    }
  ]
}

作为堆栈溢出中类似 的答案之一,提到 DefaultAzureCredential 即使显示不可用消息也能正常工作, 我尝试继续使用 @azure/identity

获取 API 管理服务的报告

const client = new ApiManagementClient(credentials, subscriptionId);

const resourceGroupName = process.env.AZURE_RESOURCE_GROUP;
const serviceName = process.env.AZURE_SERVICE_NAME;
const filter = "callCountSuccess";

client.reports
    .listBySubscription(
        resourceGroupName,
        serviceName,
        filter
    )
    .then((result) => {
        console.log(JSON.stringify(result));
    })
    .catch((err) => {
        console.log(err);
    });

但由于这也给出了 403 错误,

response: {
    body: `{"error":
    {"code":"AuthorizationFailed",
    "message":
    "The client 'cxxxxxxxxxxxxxxx569' with object id 'cxxxxxxxxxxxxxxx569' 
    does not have authorization to perform action 'Microsoft.ApiManagement/service/reports/read' 
    over scope '/subscriptions/85xxxxxxx3c5/resourceGroups/axxxb/providers/Microsoft.ApiManagement/service/Axxxx/reports/bySubscription' 
    or the scope is invalid. 
    If access was recently granted, please refresh your credentials."}}`,
    headers: HttpHeaders { _headersMap: [Object] },
    status: 403
  },

编辑

我已将 API 管理服务 Reader 角色添加到 Api 管理服务,但出现与上述相同的错误。

您 运行 进入 AuthorizationFailed 错误的原因是您似乎没有为您的服务主体分配任何权限(RBAC 角色)。

默认情况下,服务主体没有任何权限对 Azure 订阅执行操作。您需要通过为您的服务主体分配合适的 RBAC 角色来明确授予适当的权限。

您可以尝试在订阅、资源组或 API 管理资源级别将 Reader 角色分配给您的服务主体。您可能会发现此 link 有帮助:https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-steps.

一旦分配了适当的角色,您就不会收到此错误。