如何使用联合凭据通过JavaScript SDK登录Microsoft Graph
基于Azure AD联合凭据的GitHub Actions调用Microsoft Graph实操流程
第一步:给已注册的Azure AD应用配置联合凭据
- 进入Azure AD「应用注册」页面,找到你已经创建好的应用,在左侧菜单选择「证书和密码」,切换到「联合凭据」标签页
- 点击「添加凭据」,凭据场景选择GitHub Actions deploying Azure resources
- 按照页面提示填写GitHub关联配置:
- 组织名:填写你的GitHub账号或所属组织名称,和仓库路径中的所有者字段一致
- 仓库名:填写存放工作流文件的GitHub仓库名称,和仓库路径中的仓库名字段一致
- 实体类型:根据工作流触发规则选择,分支触发选
Branch、PR触发选Pull Request、指定部署环境触发选Environment,比如主分支触发就选Branch,对应值填main - 名称:给该联合凭据设置一个可识别的自定义名称即可
- 保存配置后,记录下应用的「应用程序(客户端) ID」、「目录(租户) ID」,后续配置需要用到
注意:全程不需要创建客户端密钥、上传证书,联合凭据会自动完成GitHub与Azure AD的信任链校验,不需要任何静态凭据。
第二步:配置GitHub仓库的工作流权限
- 打开对应GitHub仓库,进入「Settings」->「Actions」->「General」,下拉找到「Workflow permissions」板块
- 选中Read and write permissions,如果工作流包含PR触发场景,额外勾选「Allow GitHub Actions to create and approve pull requests」后保存
- 不需要在仓库Secrets中存储任何Azure相关密钥,联合凭据模式不依赖静态密钥配置。
第三步:编写GitHub Actions工作流完成认证与Graph调用
直接使用官方Azure登录Action获取令牌即可,不需要手写令牌请求逻辑,以下为JavaScript/TypeScript场景的可直接复用示例:
name: Call Microsoft Graph on: push: branches: [ main ] jobs: call-graph: runs-on: ubuntu-latest permissions: id-token: write # 必须开启,用于获取GitHub OIDC令牌完成联合认证 contents: read steps: - uses: actions/checkout@v4 # 联合凭据登录Azure AD - name: Azure AD Login with Federated Credential id: login uses: azure/login@v2 with: client-id: ${{ vars.AZURE_CLIENT_ID }} # 之前记录的应用ID,存在仓库Variables即可,不需要放Secrets tenant-id: ${{ vars.AZURE_TENANT_ID }} # 之前记录的租户ID subscription-id: "" # 不调用Azure资源管理接口可留空 enable-AzPSSession: false audience: api://AzureADTokenExchange # 联合凭据校验固定值 # 方式1:直接通过REST调用Graph API - name: Call Graph via REST run: | ACCESS_TOKEN=$(az account get-access-token --resource-type ms-graph --query accessToken -o tsv) # 示例:调用接口获取应用有权限访问的用户列表 curl -s -H "Authorization: Bearer $ACCESS_TOKEN" https://graph.microsoft.com/v1.0/users # 方式2:通过Microsoft Graph JS SDK调用 - name: Setup Node runtime uses: actions/setup-node@v4 with: node-version: 20 - name: Install SDK dependencies run: npm install @microsoft/microsoft-graph-client @azure/identity - name: Run SDK call script run: node call-graph.js env: AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }} AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
对应目录下的call-graph.js脚本内容:
const { Client } = require("@microsoft/microsoft-graph-client"); const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials"); const { ClientAssertionCredential } = require("@azure/identity"); // 不需要传入客户端密钥,直接通过GitHub运行时注入的OIDC令牌完成认证 const getGitHubOidcToken = async () => { if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) throw new Error("Not running in GitHub Actions environment"); const tokenRes = await fetch(`${process.env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=api://AzureADTokenExchange`, { headers: { Authorization: `Bearer ${process.env.ACTIONS_RUNTIME_TOKEN}` } }); const tokenData = await tokenRes.json(); return tokenData.value; }; const credential = new ClientAssertionCredential( process.env.AZURE_TENANT_ID, process.env.AZURE_CLIENT_ID, getGitHubOidcToken ); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ["https://graph.microsoft.com/.default"] }); const graphClient = Client.initWithMiddleware({ authProvider }); // 示例:调用接口获取用户列表 async function main() { const userList = await graphClient.api("/users").get(); console.log(userList); } main();
常见问题排查
- 工作流Job必须配置
id-token: write权限,否则无法获取GitHub OIDC令牌,会直接报联合认证失败 - 联合凭据配置的实体类型、匹配值必须和工作流实际触发场景完全一致,比如配置仅允许main分支触发时,PR触发的工作流无法通过认证
- 记得给Azure AD应用添加需要的Microsoft Graph权限,配置完成后点击「授予管理员同意」,否则调用接口会返回403错误
- 不需要参考客户端密钥/证书类的认证逻辑,
ClientAssertionCredential是官方专门为联合凭据场景提供的认证提供者,和JS SDK的认证体系完全兼容,不需要传入clientSecret参数。
内容的提问来源于stack exchange,提问作者noonenine
相关产品推荐
相关产品推荐

