【问题标题】:Error running Invoke-RestMethod with $(System.AccessToken) in a build task在构建任务中使用 $(System.AccessToken) 运行 Invoke-RestMethod 时出错
【发布时间】:2021-10-25 05:13:48
【问题描述】:

我在尝试使用 $(System.AccessToken) 的值作为凭据访问 REST API 时收到 401(大概)。我正在运行的管道与我正在使用的 API URL 位于同一 ADS 2020 本地服务器上。

构建日志中的错误消息如下:

TF400813:资源不可用于匿名访问。需要客户端身份验证。 - Azure DevOps 服务器

this technique 的启发,这是我的 PowerShell 内联脚本任务中的代码:

$Params = @{
  ContentType = 'application/json'
  Headers = @{ Authorization = 'Bearer $(System.AccessToken)' }
  Method = 'Get'
  Uri = 'http://host/collection/project/_apis/build/builds/' + $(Build.BuildId) + '?api-version=6.0'
}

$Result = Invoke-RestMethod @Params

我也试过这个,借用this answer:

$Params = @{
  ContentType = 'application/json'
  Method = 'Get'
  Uri = 'http://$(System.AccessToken)@host/collection/project/_apis/build/builds/' + $(Build.BuildId) + '?api-version=6.0'
}

$Result = Invoke-RestMethod @Params

我已注意打开Allow scripts to access the OAuth token 选项,如here 所述。

关于它的奇怪之处在于它第一次工作(上面的第一个代码块)。现在,无论我尝试什么,我总是得到上述错误。

如何在 Build 任务中使用 $(System.AccessToken) 的值来访问同一服务器上的 REST API?

--编辑--

我也尝试过备用变量语法:

$BuildId = $env:BUILD_BUILDID
$Token = $env:SYSTEM_ACCESSTOKEN

$Params = @{
  ContentType = 'application/json'
  Headers = @{ Authorization = 'Bearer $Token' }
  Method = 'Get'
  Uri = 'http://host/collection/project/_apis/build/builds/' + $BuildId + '?api-version=6.0'
}

$Result = Invoke-RestMethod @Params

【问题讨论】:

  • 两点... [1] $(System.AccessToken) 不是有效的 powershell 代码。不能以这种方式定义变量。它实际上在做什么? ///// [2] 'Bearer $(System.AccessToken)' 在单引号中。所以,即使奇怪的变量是有效的......它根本不会被扩展。您只会得到单引号中显示的确切文本。
  • 其实是在内联脚本中。当脚本内联时,系统/构建/发布变量可用。但是,尽管如此,当使用 $env:SYSTEM_ACCESSTOKEN 语法时,我也得到了相同的结果。我已经更新了我的问题以反映这一点。
  • 感谢您提出关于单引号的观点。直到现在,我一直认为它们是双打的同义词——但一些快速测试表明它们不是。我已经相应地更新了我的答案。
  • 内联脚本不是 powershell 本身。它们是在另一个上下文中可能运行 powershell的东西。您可能会在您的问题中提到外部环境。 ///// 是的,这两种引号之间的区别在于相当有意义。 [咧嘴]
  • you likely otta mention that outer environment in your Question 啊,但我做到了!第四段;-)

标签: powershell authentication azure-devops-server-2020


【解决方案1】:

经过一番苦恼,我终于找到了有效的组合:

$BuildId = $env:BUILD_BUILDID
$Token = $env:SYSTEM_ACCESSTOKEN

$Params = @{
  ContentType = "application/json"
  Method = "Get"
  Uri = "http://host/collection/project/_apis/build/builds/$BuildId"
}

$Result = Invoke-RestMethod @Params -Headers @{ Authorization = "Bearer $Token" }

我一时兴起尝试了它。我不知道为什么这会通过而其他人没有,但这没关系。它运行。我在里面贴了一面旗帜。

【讨论】:

  • 看起来你摆脱了inline script 的东西。这很可能就是它的“原因”。 [咧嘴]
  • 它仍然是内联的。这就是looks like 的全部内容。多亏了您的单引号提示,我得以简化了很多。
  • 啊!我看到您确实删除了那个非常奇怪的 $(stuff.here) 语法。这就是我的意思......抱歉造成混乱。 [脸红]
  • NP。这是 Azure DevOps Server 中 Agent/Build/Release/System variables 的语法。它相当广泛。
  • 感谢您的澄清! [咧嘴]
猜你喜欢
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多