我试图通过在Azure DevOps wiki using it's Rest API中创建新页面来自动在Azure DevOps发布管道中创建发行说明。
我遇到的问题是我正在使用PowerShell脚本任务将其发布到Rest API,并且我想避免使用个人访问令牌(PAT),而改为使用OAuth >。 PAT到期了,我不希望PAT到期时所有发行版本突然失败。通过在构建代理的上下文中使用OAuth运行PowerShell脚本,可以避免此过期问题。在PowerShell脚本任务所在的版本的代理作业中,我选中了“允许脚本访问OAuth令牌”。
为简单起见,我正在运行以下 inline PowerShell脚本来测试使用OAuth("Bearer $env:SYSTEM_ACCESSTOKEN"
)创建新的Wiki页面:
$uri = "https://dev.azure.com/{organization}/{project}/_apis/wiki/wikis/{wikiIdentifier}/pages?api-version=5.0&path=/Release%20Notes/Customers%20API/Release-299%20[Build:%2020191010.1]";
try {
$response = Invoke-RestMethod `
-Method PUT $uri `
-Headers @{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} `
-ContentType "application/json" `
-Body $json
} catch {
Write-Host "Message: " $_.Exception.Message;
Write-Host "StatusCode: " $_.Exception.Response.StatusCode.value__ ;
Write-Host "StatusDescription: " $_.Exception.Response.StatusDescription;
}
如果我使用邮递员和个人访问令牌对上述URL执行HTTP PUT,则将成功创建新的Wiki页面。但是,如果我在Azure DevOps中的发行版上下文中运行上述PowerShell脚本,则会收到HTTP 400“错误请求”响应。我觉得这很奇怪,因为类似的PowerShell脚本任务可以查询Wiki的Rest API以确保页面的存在而没有错误。
是否无法通过Wiki的Rest API使用Bearer令牌(OAuth)创建新的Wiki页面,或者我做错了什么?
答案 0 :(得分:5)
是否无法使用Bearer令牌创建新的Wiki页面 (OAuth)通过Wiki的Rest API?
当然可以。您可以在本地使用PAT令牌执行的所有rest api,都可以在Powershell任务中使用System.AccessToken
以编程方式运行。
对于您面临的错误,实际上,如果您只是Write-Host $response
,则错误消息将使您更加清晰:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"The wiki page operation failed with message : User does not have write permissions for this wiki.","typeName":"Microsoft.TeamFoundation.Wiki.Server.WikiPageOperationFailedException,
Microsoft.TeamFoundation.Wiki.Server","typeKey":"WikiPageOperationFailedException","errorCode":0,"eventId":3000}
的确,这是您需要关注的根本错误。
在Azure Devops管道中使用Powershell任务运行 Rest api 时,此时,此api的请求用户帐户为 {Projectname} Build service({Orgname})强>。换句话说,在构建期间请求添加Wiki页面的用户是 {Projectname}构建服务({Orgname}),这是一个权限范围仅在管道中的构建服务帐户。
此外,由于Wiki托管在存储库中,因此要解决此问题,您必须将此 Project Build service(组织名称)帐户添加到“存储库权限”组中,并确保其Contribute
权限为允许。因此,此构建服务帐户可以具有足够的权限来添加Wiki页面:
(公共是我的项目名称,ForMerlin是我的组织名称)
为了让您更清楚地了解为什么打印出400 Bad request error
后收到this non-permission error
而不是$_.Exception.Message;$_.Exception.Response.StatusCode.value__ ; $_.Exception.Response.StatusDescription;
的原因,我重现了此问题,然后检查了我们的后端IIS日志。
实际上,执行此api时,服务器正在调用Microsoft.TeamFoundation.Wiki.Web.Controllers.WikiPagesController.CreateOrUpdatePage
来打包“请求正文” ,这将发送到所使用的下一个操作方法。 (注意:此“请求正文”与我们在rest API中使用的普通请求正文不同。在这里,我指的是已完成的服务器,即服务器所需要的)。在其参数中,包含一个可以代表用户的参数:callerName
。
正如我之前提到的,调用此API请求的用户帐户是构建服务帐户,并且其权限范围不满足服务器要求。因此,服务器所需的此“请求正文”无效。然后,您使用命令$_.Exception.Response.StatusCode.value__
收到了400条代码。