使用 OAuth 和 PowerShell 更新 Azure DevOps Wiki 页面

Poo*_*eld 6 azure-powershell azure-devops azure-pipelines azure-devops-rest-api

我试图通过使用它的 Rest APIAzure DevOps wiki 中创建一个新页面来自动在 Azure DevOps 发布管道中创建发行说明。

我遇到的问题是我使用 PowerShell 脚本任务发布到 Rest API,我想避免使用个人访问令牌 (PAT) 并改用 OAuth。PAT 到期,我不希望所有版本在 PAT 到期时突然失败。通过在构建代理的上下文中使用 OAuth 运行 PowerShell 脚本,我可以避免此过期问题。我在代理作业中选中了“允许脚本访问 OAuth 令牌”以获取 PowerShell 脚本任务所在的版本。

为简单起见,我正在运行以下内联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;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 Postman 和个人访问令牌对上面的 URL 执行 HTTP PUT,则成功创建了新的 wiki 页面。但是,如果我在 Azure DevOps 中的发布上下文中运行上述 PowerShell 脚本,则会收到 HTTP 400“错误请求”响应。我觉得这很奇怪,因为类似的 PowerShell 脚本任务可以在没有错误的情况下查询 wiki 的 Rest API 是否存在页面。

是否无法通过 wiki 的 Rest API 使用不记名令牌 (OAuth) 创建新的 Wiki 页面,或者我做错了什么?

Mer*_*SFT 6

是否无法通过 wiki 的 Rest API 使用不记名令牌 (OAuth) 创建新的 Wiki 页面?

当然是的,这是可能的。您可以在本地使用 PAT 令牌执行的任何其余 api,都可以System.AccessToken在 Powershell 任务中以编程方式运行。

对于你所面临的错误,事实上,如果你只是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}
Run Code Online (Sandbox Code Playgroud)

确实,这是您需要关注的根本错误原因。

当您在 Azure Devops 管道中使用 powershell 任务运行Rest api时,此时此 api 的请求用户帐户为{Projectname} Build service({Orgname})。也就是说,在构建过程中请求添加wiki页面的用户是{Projectname} Build service({Orgname}),这是一个权限范围仅在管道中的构建服务帐户。

此外,由于 Wiki 托管在 Repository 中,要解决此问题,您必须将此Project Build service(Org name)帐户添加到您的 Repository Permission 组中,并确保其Contribute权限为Allow。因此这个构建服务帐户可以有足够的权限来添加 wiki 页面:

在此处输入图片说明

(Public 是我的项目名称,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请求的用户账号是构建服务账号,其权限范围不符合服务器要求。所以,服务器需要的这个“请求体”是无效的。然后您通过命令收到 400 代码$_.Exception.Response.StatusCode.value__