admin管理员组文章数量:1122791
I have an Azure CLI task in a release pipeline that I would like to make an API call from back to the same project. The task is executing under a Service Principal, and it makes available the servicePrincipalId
, servicePrincipalKey
and tenantId
to the script.
How can I use the Service Principal's credentials to authenticate a Invoke-RestMethod
API request?
I have an Azure CLI task in a release pipeline that I would like to make an API call from back to the same project. The task is executing under a Service Principal, and it makes available the servicePrincipalId
, servicePrincipalKey
and tenantId
to the script.
How can I use the Service Principal's credentials to authenticate a Invoke-RestMethod
API request?
- This question is similar to: How to use Service Principal Authentication (Bearer Token) in Powershell for DevOps without being asked to sign in?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – akseli Commented Nov 21, 2024 at 22:52
- @akseli - agreed, there are similar elements. I think the difference with mine is, according to the answers below, I cannot use the three pieces directly. I have to get an access token to make the call. – end-user Commented Nov 22, 2024 at 12:12
3 Answers
Reset to default 0You can use the Service Principal's credentials to authenticate a Invoke-RestMethod API request with the servicePrincipalId
, servicePrincipalKey
and tenantId
.
First, you can check the document to learn about Use service principals & managed identities in Azure DevOps. To use the Service Principal's credentials, we should add the service principal to Azure DevOps organization.
Here are the steps:
- Find and copy the App registration name by clicking the Manage App registration in the service connection.
- Add the App registration to your organization in the Users page. You should be a member of the Project Collection Administrators group.
- Now you can use the Service Principal's credentials to make an API call from back to the same project in the azure cli task.
Here are the sample YAMLs:
- Use
az account get-access-token
command to get the token. This is also mentioned in this Q&A Can I use a service principal or managed identity with Azure CLI?.
- task: AzureCLI@2
inputs:
azureSubscription: 'Test'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "Obtain access token for Service Connection identity..."
$accessToken = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query "accessToken" --output tsv
Write-Host "Use access token with Azure DevOps REST API to list projects in the organization..."
$uri = "https://dev.azure.com/orgname/_apis/projects?api-version=7.1-preview.1"
$headers = @{
Accept = "application/json"
Authorization = "Bearer $accessToken"
}
$response =Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$response | ConvertTo-Json
- Use the
servicePrincipalId
,servicePrincipalKey
andtenantId
to get the token.
- task: AzureCLI@2
displayName: Use servicePrincipalId, servicePrincipalKey and tenantId
inputs:
azureSubscription: 'Test'
scriptType: 'ps'
addSpnToEnvironment: true
scriptLocation: 'inlineScript'
inlineScript: |
$tenantId = $env:tenantId
$clientId = $env:servicePrincipalId
$clientSecret = $env:servicePrincipalKey
$resource = "499b84ac-1321-427f-aa17-267ca6975798" #(the Azure DevOps resource's UUID is 499b84ac-1321-427f-aa17-267ca6975798)
$body = @{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
resource = $resource
}
# Get the token
$tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/token" -Body $body
$token = $tokenResponse.access_token
Write-Host "Use servicePrincipalId, servicePrincipalKey and tenantId with Azure DevOps REST API to list project in the organization..."
$uri = "https://dev.azure.com/orgname/_apis/projects?api-version=7.1"
$headers = @{
Accept = "application/json"
Authorization = "Bearer $token"
}
$response =Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$response | ConvertTo-Json
By the way, there is another easy way make an API call from back to the same project is to use the System.AccessToken. This way, we don't need to add the service principal to Azure DevOps organization.
- task: AzureCLI@2
displayName: Use System.AccessToken
inputs:
azureSubscription: 'Test'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "Use System.AccessToken with Azure DevOps REST API to list project in the organization..."
$uri = "https://dev.azure.com/orgname/_apis/projects?api-version=7.1"
$headers = @{
Accept = "application/json"
Authorization = "Bearer $(System.AccessToken)"
}
$response =Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$response | ConvertTo-Json
Considering that you use azure cli task
and service principal
, I guess your service principal is used to create service connection. Am I right?
If my guess is correct [if not, please ignore my answer -_-], you don't need to get the actual value of the service principal, but directly get the token, and then use the token to send the Invoke-RestMethod
request. az account get-access-token
Below is a sample to illustrate the case (get azure subscription):
pool:
vmImage: windows-latest
steps:
- task: AzureCLI@2
displayName: 'Azure CLI'
inputs:
scriptType: ps
scriptLocation: inlineScript
azureSubscription: 'DevOpsSub1Connection-Test'
inlineScript: |
$subscriptionId = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxx'
$token = $(az account get-access-token --resource-type arm --query accessToken --output tsv)
$headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer " + $token
}
$uri = "https://management.azure.com/subscriptions/{0}?api-version=2022-12-01" -f $subscriptionId
$response = Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
$response | ConvertTo-Json -Depth 10
Ok, I was able to use @Miao Tian-MSFT's answer to get the token I needed.
$accessToken = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query "accessToken" --output tsv
However, I also later discovered the piece I was missing - on the Agent job, be sure to check the "Allow scripts to access the OAuth token" box. That's what provides the $System.AccessToken
to the scripts (making the above call unnecessary).
本文标签:
版权声明:本文标题:powershell - How do I provide service principal's authorization for an API call in a DevOps pipeline - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736306761a1933074.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论