FunctionApp调用ADO API遇ExpiredAuthenticationToken错误求助
检查PAT权限与有效期
确认PAT是否勾选了**Agent Pools (Read)**权限(访问代理池API的必要权限),同时验证PAT的有效期是否真的未过期——别忽略本地测试时PAT还在有效期,部署到Function App时刚好过期的情况。另外还要确认PAT没有被意外撤销。不要硬编码PAT,用Function App配置存储
硬编码PAT容易出现复制粘贴错误,或者Function App环境下的字符解析问题。把PAT放到Function App的应用程序设置里(比如键名设为ADO_PAT),脚本里用$env:ADO_PAT读取,既安全又能避免编码问题。统一API版本,修正请求参数
你的脚本里API URL用的是api-version=5.1,但ContentType里又写了api-version=6.0,版本不一致会导致ADO返回异常。把API版本统一,比如都用6.0,同时ContentType里不需要带api-version参数,单独放在URL里即可。排查Function App网络环境
如果Function App配置了VNet集成或者出站防火墙规则,可能导致请求无法正确到达ADO API,或者请求头被篡改,引发令牌验证失败。可以临时关闭VNet集成测试,或者确认出站规则允许访问dev.azure.com。重新生成PAT并验证编码
有时候PAT的Base64编码在Function App环境下可能因为编码格式问题出错。可以在Function App里输出编码后的令牌,和本地运行的结果对比是否一致;或者直接重新生成一个新的PAT,再部署测试。
修正后的脚本示例:
# 从Function App应用设置读取PAT $personalToken = $env:ADO_PAT if (-not $personalToken) { Write-Error "未找到ADO_PAT环境变量" exit 1 } # 编码PAT生成认证头 $patToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$personalToken")) $repoHeader = @{"Authorization"="Basic $patToken"} # 统一API版本的请求URL $repoUrl = "https://dev.azure.com/org/_apis/distributedtask/pools?api-version=6.0" try { $output = Invoke-RestMethod -Uri $repoUrl -Method Get -ContentType "application/json; charset=utf-8" -Headers $repoHeader -MaximumRedirection 10 # 输出代理池名称 foreach ($outputValue in $output.value) { Write-Output $outputValue.name } } catch { # 捕获错误并输出详细信息,方便排查 Write-Error "请求失败: $($_.Exception.Message)" if ($_.Exception.Response) { Write-Error "状态码: $($_.Exception.Response.StatusCode.value__)" $responseStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($responseStream) $responseContent = $reader.ReadToEnd() Write-Error "响应内容: $responseContent" } }
内容的提问来源于stack exchange,提问作者sphtd97

