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

Using OAuth and PowerShell to Update Azure DevOps Wiki Pages

我正在尝试通过在 Azure DevOps wiki using it's Rest API.

中创建一个新页面来在 Azure DevOps 发布管道中自动创建发行说明

我遇到的问题是我正在使用 PowerShell 脚本任务 post 其他 API 我想避免使用个人访问令牌 (PAT) 改为使用 OAuth。 PAT 到期,我不希望所有版本在 PAT 到期时突然失败。通过 运行 在构建代理的上下文中使用 OAuth 连接 PowerShell 脚本,我可以避免这个过期问题。我已在代理作业中检查了 PowerShell 脚本任务所在版本的 "Allow scripts to access the OAuth token"。

为简单起见,我运行使用以下 内联 PowerShell 脚本来测试使用 OAuth 创建新的 wiki 页面 ("Bearer $env:SYSTEM_ACCESSTOKEN") :

$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;
}

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

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

Is it not possible to create a new Wiki page using a Bearer token (OAuth) via the wiki's Rest API?

当然可以,这是可能的。您可以在本地使用 PAT 令牌执行的任何其余 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任务api休息时,此时,请求此[=64=的用户帐户] 是 {Projectname} 构建服务({Orgname})。也就是说,在构建过程中请求添加wiki页面的用户是{Projectname} Build service({Orgname}),这是一个只有权限范围的构建服务账号在管道中。

此外,由于 Wiki 托管在存储库中,要解决此问题,您必须添加此项目构建服务(组织名称) 帐户进入您的 Repository Permission 组,并确保其 Contribute 权限为 Allow。因此这个构建服务帐户可以有足够的权限来添加 wiki 页面:

(Public 是我的项目名,ForMerlin 是我的组织名)


为了让您更清楚为什么在打印 $_.Exception.Message;$_.Exception.Response.StatusCode.value__ ; $_.Exception.Response.StatusDescription; 后收到 400 Bad request error 而不是 this non-permission error,我重现了这个问题,然后检查我们的后端 IIS 日志。

执行这个api的时候,其实是服务端在调用Microsoft.TeamFoundation.Wiki.Web.Controllers.WikiPagesController.CreateOrUpdatePage打包"request body",发送到下一个操作使用的方法。 (注意:这个"request body"不等于我们在休息时使用的普通API。这里我指的是完成的,也就是需要的服务器)。在它的参数中,有一个可以代表用户:callerName.

如前所述,调用此API请求的用户帐户是构建服务帐户,其权限范围不符合服务器要求。所以,这个服务器需要的 "request body" 是无效的。然后你收到了 400 代码和命令 $_.Exception.Response.StatusCode.value__.