GitHub OIDC换取Entra ID访问令牌失败,求解决方案及参考文档
GitHub OIDC换取Entra ID访问令牌失败排查与修复
问题背景
已配置带有GitHub联合凭据的Entra ID应用注册,且测试工作流可成功认证Azure订阅,但在创建工作流通过GitHub OIDC令牌换取Entra ID访问令牌以调用Microsoft Graph时执行失败,报错如下:
Write-Error: Authentication failed: The term '***' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Error: Process completed with exit code 1
错误原因分析
- 令牌直接展开导致PowerShell语法错误:原代码在PowerShell步骤中直接使用
${{ steps.generate_oidc_token.outputs.token }}赋值给变量,GitHub Actions会将令牌明文展开,令牌中的特殊字符会被PowerShell误解析为命令或语法元素,触发“术语未识别”错误。 - OIDC令牌获取冗余且错误:
core.getIDToken()已经返回完整的GitHub OIDC ID令牌,无需再通过ACTIONS_ID_TOKEN_REQUEST_URL二次请求。 - 令牌交换参数错误:使用
urn:ietf:params:oauth:grant-type:token-exchange和on_behalf_of不符合GitHub OIDC联合认证的场景,应使用urn:ietf:params:oauth:grant-type:jwt-bearer授权类型。
修复后的工作流代码
name: Connect to Entra using OIDC on: workflow_dispatch: permissions: id-token: write # 必须配置,用于获取OIDC令牌 contents: read # 可选,根据实际需求调整 jobs: connect-entra: runs-on: ubuntu-latest environment: production steps: - name: 安装Microsoft Graph PowerShell SDK run: | pwsh -Command " Set-PSRepository -Name PSGallery -InstallationPolicy Trusted Install-Module -Name Microsoft.Entra -Repository PSGallery -Scope CurrentUser -Force -AllowClobber " - name: 获取GitHub OIDC令牌 id: get_oidc_token uses: actions/github-script@v7 with: script: | const token = await core.getIDToken(); core.setOutput('oidc_token', token); - name: 换取Microsoft Graph访问令牌并调用API env: TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} OIDC_TOKEN: ${{ steps.get_oidc_token.outputs.oidc_token }} shell: pwsh run: | try { # 构造令牌交换请求体 $body = @{ client_id = $env:CLIENT_ID client_assertion_type = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer' client_assertion = $env:OIDC_TOKEN grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer' scope = 'https://graph.microsoft.com/.default' requested_token_use = 'on_behalf_of' } # 发送请求换取访问令牌 $tokenResponse = Invoke-RestMethod -Method POST ` -Uri "https://login.microsoftonline.com/$env:TENANT_ID/oauth2/v2.0/token" ` -Body $body ` -ContentType 'application/x-www-form-urlencoded' # 使用访问令牌连接Entra ID并调用Graph API Connect-Entra -AccessToken $tokenResponse.access_token Write-Host "成功连接到Entra ID" # 测试Graph API调用 $user = Get-EntraUser -Top 1 Write-Host "获取到的用户信息:" $user | Format-List } catch { Write-Error "认证失败:$($_.Exception.Message)" Write-Error "详细错误信息:$($_.ErrorDetails.Message)" exit 1 }
关键注意事项
- 联合凭据配置:确保Entra应用注册中的GitHub联合凭据配置正确,受众(Audience)需设置为
api://AzureADTokenExchange,同时匹配GitHub仓库、分支、环境等条件。 - 权限配置:工作流的
permissions.id-token必须设置为write,否则无法获取OIDC令牌。 - 模块安装:首次安装PowerShell模块时需信任PSGallery仓库,否则会触发安全提示导致安装失败。
- API权限:确保Entra应用注册已添加所需的Microsoft Graph应用权限(如
User.Read.All)并完成管理员同意。
内容的提问来源于stack exchange,提问作者D K
相关产品推荐
相关产品推荐

