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

8
我正在尝试使用Azure DevOps Rest API在Azure DevOps维基中创建新页面,以自动化生成发布说明。
我的问题是,我正在使用PowerShell脚本任务发布到Rest API,并希望避免使用个人访问令牌(PAT),而是使用OAuth。PAT会过期,我不希望所有发布在PAT过期时突然失败。通过在构建代理的上下文中使用OAuth运行PowerShell脚本,我可以避免此过期问题。我已经在发布的代理作业中勾选了“允许脚本访问OAuth令牌”。
为了保持简单,我正在运行以下内联PowerShell脚本来测试使用OAuth创建新的维基页面(“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,则可以成功创建新的维基页面。但是,如果我在Azure DevOps发布的上下文中运行上述PowerShell脚本,则会收到HTTP 400“错误请求”的响应。我觉得这很奇怪,因为类似的PowerShell脚本任务可以在没有错误的情况下查询维基的Rest API以查找页面是否存在。
无法使用Bearer令牌(OAuth)通过维基的Rest API创建新的维基页面吗?还是我做错了什么?
1个回答

9
通过Wiki的Rest API使用Bearer token(OAuth)创建新的Wiki页面是否不可行?
当然可以。任何你可以在本地使用PAT token执行的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 pipeline 中使用 Powershell 任务运行 Rest API 时,此时请求该 API 的用户账户为 {Projectname} Build service({Orgname})。换句话说,正在构建过程中请求添加 Wiki 页面的用户是 {Projectname} Build service({Orgname}),这是一个构建服务账户,其权限范围仅限于管道。

此外,由于 Wiki 托管在代码库中,为了解决这个问题,你必须将此 项目构建服务(Org name) 账户添加到代码库权限组,并确保其 Contribute 权限设置为 Allow。这样,构建服务账户就可以拥有足够的权限来添加 Wiki 页面:

enter image description here

(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__


感谢您详细的回复!Project Build Service帐户是我们Azure DevOps项目中Git存储库用户的一部分。然而,该帐户仅设置了创建标签读取权限。我假设它需要其他权限才能写入Wiki。您知道必须设置哪些其他权限才能允许吗?不幸的是,您的屏幕截图没有显示授予该帐户的权限。 - PoorInRichfield
哈哈,抱歉我的粗心大意:-) 缺少这个关键配置。为了使用项目构建服务帐户创建维基页面,请确保至少将“Contribute”权限设置为“允许”。由于维基托管在存储库中,因此创建维基页面意味着对存储库进行贡献。 - Mengdi Liang
嗨@MerlinLiang-MSFT,我们也遇到了这个错误,但是已经授予了所有权限。 {"$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}。我可以看到用户Build Service(org)具有允许贡献的权限。有什么办法可以检查正在运行管道的用户是谁?还有什么可能导致此错误? - DolceVita
1
@DolceVita 因为我不知道你组织的设置细节,你可以尝试添加 项目集构建服务(org name) 并授予它贡献权限。这是集合级别的服务帐户,我猜测你的组织可能使用这个级别的帐户而不是项目级别的帐户。你可以进入你的 组织设置 页面 -> 设置 来检查选项 将非发布管道的作业授权范围限制为当前项目 是否已启用。 - Mengdi Liang
@DolceVita 这是一个关键选项,它决定了您的组织是使用集合级别的服务帐户还是项目级别的服务帐户。 - Mengdi Liang
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接