powershell 无法在Azure DevOps管道中以非交互方式对az rest API调用进行身份验证

2ekbmq32  于 2023-06-23  发布在  Shell
关注(0)|答案(2)|浏览(185)

我正在尝试使用在管道中执行的powershell脚本来自动化Azure DevOps PAT旋转。只要我在powershell会话中运行了az login,我的脚本就能按预期工作,并且能够成功调用Pats endpoints detailed here
为了在管道中运行它,我使用Azure CLI任务,并为Azure订阅参数提供服务连接。我假设这实际上是使用服务连接为您执行“az登录”,然后在其中运行脚本。
这就是管道任务的样子:

- task: AzureCLI@2
  displayName: Rotate PAT
  inputs:
    azureSubscription: ${{ parameters.service_connection }}
    scriptType: pscore
    scriptLocation: scriptPath
    scriptPath: $(System.DefaultWorkingDirectory)/scripts/AzureDevOpsPatRotation.ps1
    arguments: '-tokenName "${{ parameters.token_name }}" -varGroupName "${{ parameters.variable_group_name }}" -varName "${{ parameters.variable_name }}" -pat "${{ parameters.pat }}"'
    addSpnToEnvironment: true
    failOnStandardError: true

然而,在运行管道时,我会遇到几个不同的错误。首先是html错误响应:

ERROR: (<!DOCTYPE html >
<html>
  <head>
    <title>Access Denied: 00000000-0000-0000-0000-000000000000 needs the following permission(s) on the resource Subjects to perform this action: Read by public identifier</title>
    <style type="text/css">html {
    height: 100%;
}

...

<div class="error-info">
    <div class="title">500 - Something went wrong!</div>
    <div class="details">We've encountered an error and cannot fulfill this request. We will trace the error and get a fix out soon.</div>
    <div class="reference-data">
      <div>2/21/2023 12:44:31 AM (UTC)</div>
      <div>67cec8df-d6be-4998-a726-5e19c7f091d4</div>
    </div>
    <div class="action-container">
      <a class="action" href="https://go.microsoft.com/fwlink/?LinkID=328778">
        <span>Contact support</span>
      </a>
    </div>
</div>

第二个是JSON控制台错误:

ERROR: ({"$id":"1","innerException":null,"message":"TF401444: Please sign-in at least once as ********-****-****-****-************\\********-****-****-****-************\\********-****-****-****-************ in a web browser to enable access to the service.","typeName":"Microsoft.TeamFoundation.Framework.Server.UnauthorizedRequestException, Microsoft.TeamFoundation.Framework.Server","typeKey":"UnauthorizedRequestException","errorCode":0,"eventId":3000})
Interactive authentication is needed. Please run:
az logout
az login
ERROR: argument --value: expected one argument

我查找了第二个错误引用的guid,它似乎是服务连接中使用的服务主体的objectID。
我知道这个错误是明确地说需要一个交互式的身份验证,但我的问题是,是否有办法绕过这个问题,使这种非交互式的方式,以便PAT轮换可以在流水线中自动化。有什么建议吗?

vjrehmav

vjrehmav1#

azureSubscription: ${{ parameters.service_connection }}为您提供了一个SPN,Azure DevOps对SPN的支持将于2023年3月发布,但我还没有测试它。相反,您可以使用旧方法,使用$(System.AccessToken)将其设置为使用az rest调用时的Bearer令牌头。下面是一个bash脚本的例子,powershell应该是类似的

- task: AzureCLI@2
  displayName: Az rest
  inputs:
    azureSubscription: ${{ parameters.service_connection }}
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
      az rest \
          --headers "Authorization=Bearer $SYSTEM_ACCESSTOKEN" \
          --resource 499b84ac-1321-427f-aa17-267ca6975798 \
          --url <url>
    env:
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)

顺便说一句,我有一个大问题,如果${{ parameters.service_connection }}在这里工作,它需要在编译时指定。为了测试,你可以运行任何其他标准的azcli(不是az rest)命令来查询azure资源吗?

wrrgggsh

wrrgggsh2#

TL;DR

不允许服务主体执行此操作。你需要一个合适的AAD用户来做这件事。您可以在管道中的az cli中使用以下内容登录(您可以在Key Vault中存储用户名和密码,并且必须为此用户禁用MFA):

az login -u <username> -p <password>

查看详情

您收到Read by public identifier错误的原因是服务连接无法访问Azure Devops组织。您可以通过添加应用程序注册的服务主体来解决此问题,该应用程序注册表示与Azure Devops组织的服务连接(是的,您可以这样做。)并且您将拥有如下内容:

但很快你就会在管道中发现另一个更有意义的错误:

{
    "$id": "1",
    "innerException": null,
    "message": "Service principals are not allowed to perform this  action.",
    "typeName": "Microsoft.TeamFoundation.Framework.Server.InvalidAccessException, Microsoft.TeamFoundation.Framework.Server",
    "typeKey": "InvalidAccessException",
    "errorCode": 0,
    "eventId": 3000
}

相关问题