通过 Az 模块创建 azure 应用程序并使用 powershell 分配 API 权限
Create azure application through Az module and assign API permissions using powershell
我写了一个脚本,它使用 Az 模块创建 azure 应用程序,创建密钥,分配所有者。但是分配 API 权限会得到 insufficient permission error
。该用户是管理员用户。仍然无法分配 API 权限。我做错了什么?
$ErrorActionPreference = 'Stop'
Connect-AzAccount
Import-Module Az.Resources
$tenant = Get-AzTenant
Set-AzContext -TenantId $tenant.Id
$AppName = Read-Host -Prompt 'Enter Application name '
$myApp = New-AzADApplication -DisplayName $AppName -IdentifierUris "http://$AppName.com"
Write-Host "App registered.."
$sp = New-AzADServicePrincipal -ApplicationId $myApp.ApplicationId -Role Owner
Write-Host "Service principal registered.."
$startDate = Get-Date
$endDate = $startDate.AddYears(100)
$secret = Read-Host -Prompt 'Enter App Secret Key ' -AsSecureString
$secPassword = ConvertTo-SecureString -AsPlainText -Force -String $secret
New-AzADAppCredential -ObjectId $myApp.ObjectId -StartDate $startDate -EndDate $endDate -Password $secPassword
$ResourceAppIdURI = "https://graph.windows.net/"
# $authority = "https://login.microsoftonline.com/$tenant/oauth2/v2.0/token"
$authority = "https://login.windows.net/$tenant/oauth2/token"
$ClientCred = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential" -ArgumentList $myApp.ApplicationId, $secret
$AuthContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority,$false
$AuthContext.TokenCache.Clear()
Start-Sleep -Seconds 10
$Token = $Authcontext.AcquireTokenAsync($ResourceAppIdURI, $ClientCred)
$AuthHeader = @{"Authorization" = $Token.Result.CreateAuthorizationHeader();"Content-Type"="application/json"}
$url = "https://graph.windows.net/$tenant/applications/$($myApp.ObjectID)?api-version=1.6"
Write-Host "URL: " $url
$postData = "{`"requiredResourceAccess`":[{`"resourceAppId`":`"00000003-0000-0000-c000-000000000000`",
`"resourceAccess`":[{`"id`":`"e1fe6dd8-ba31-4d61-89e7-88639da4683d`",`"type`":`"Scope`"}]}]}";
$result = Invoke-RestMethod -Uri $url -Method "PATCH" -Headers $AuthHeader -Body $postData
Write-Host "Result of App API permission: " $result
如果要调用 Azure AAD graph API 以使用 OAuth 2.0 客户端凭据流分配权限,我们需要提供足够的权限(Azure AD Graph -> Aapplication permissions -> Application.ReadWrite.All)
此外,关于如何使用PowerShell为AD应用程序分配权限,我们也可以使用PowerShell模块AzureAD。
例如
Connect-AzureAD
$AppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "00000003-0000-0000-c000-000000000000";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "";
Type = ""},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "";
Type = ""}
}
Set-AzureADApplication -ObjectId <the app object id> -RequiredResourceAccess $AppAccess
更新
根据我的测试,当我们使用Az模块时,我们可以使用以下方法获取访问令牌并调用AAD graph rest API。但请注意,当您使用该方法时,您使用的帐户 运行 Connect-AzAccount
应该是 Azure AD Global Admin
Connect-AzAccount
$context =Get-AzContext
$dexResourceUrl='https://graph.windows.net/'
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account,
$context.Environment,
$context.Tenant.Id.ToString(),
$null,
[Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never,
$null, $dexResourceUrl).AccessToken
# assign permissions
$headers =@{}
$headers.Add("Content-Type", "application/json")
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($token)")
$body = "{
`n `"requiredResourceAccess`": [{
`n `"resourceAppId`": `"00000003-0000-0000-c000-000000000000`",
`n `"resourceAccess`": [
`n {
`n `"id`": `"405a51b5-8d8d-430b-9842-8be4b0e9f324`",
`n `"type`": `"Role`"
`n },
`n {
`n `"id`": `"09850681-111b-4a89-9bed-3f2cae46d706`",
`n `"type`": `"Role`"
`n }
`n ]
`n }
`n ]
`n}
`n"
$url ='https://graph.windows.net/hanxia.onmicrosoft.com/applications/d4975420-841f-47d5-a3d2-0870901f13cd?api-version=1.6'
Invoke-RestMethod $url -Method 'PATCH' -Headers $headers -Body $body
#check if adding the permissions you need
$headers =@{}
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($token)")
$url ='https://graph.windows.net/hanxia.onmicrosoft.com/applications/<aad application object id>?api-version=1.6'
$response=Invoke-RestMethod $url -Method 'GET' -Headers $headers
$response.requiredResourceAccess | ConvertTo-Json
在我的例子中,最简单的方法是结合 Azure-powershell
模块和 Az cli
模块
所以,一旦我创建了我的新应用程序:
$myApp = New-AzADApplication -DisplayName $AppName -IdentifierUris "http://$AppName.com"
然后我将使用 Az Cli
登录到 azure,例如:
- 添加一些 api 权限
- 授予这些权限目录管理员同意(如果需要)
. { $azcliLogin = az login }
. { az account set --subscription $config.subscriptionId }
. { az ad app permission add --id $myApp.appid --api 00000002-0000-0000-c000-000000000000 --api-permissions 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175=Role }
. { $appApiGrant = az ad app permission grant --id $config.azureAccess.appid --api 00000002-0000-0000-c000-000000000000 }
. { az ad app permission admin-consent --id $myApp.appid }
其中:
--api 00000002-0000-0000-c000-000000000000
指 Microsoft Graph API
--api-permissions 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175=Role
指的是这个api上的一些角色,如Directory.ReadWrite.All
You can get the required API and API-PERMISSIONS guids from the App manifiest in Azure
通过这种方式,您可以在单个 powershell 脚本中创建具有所需授予 api 权限的应用程序。
我写了一个脚本,它使用 Az 模块创建 azure 应用程序,创建密钥,分配所有者。但是分配 API 权限会得到 insufficient permission error
。该用户是管理员用户。仍然无法分配 API 权限。我做错了什么?
$ErrorActionPreference = 'Stop'
Connect-AzAccount
Import-Module Az.Resources
$tenant = Get-AzTenant
Set-AzContext -TenantId $tenant.Id
$AppName = Read-Host -Prompt 'Enter Application name '
$myApp = New-AzADApplication -DisplayName $AppName -IdentifierUris "http://$AppName.com"
Write-Host "App registered.."
$sp = New-AzADServicePrincipal -ApplicationId $myApp.ApplicationId -Role Owner
Write-Host "Service principal registered.."
$startDate = Get-Date
$endDate = $startDate.AddYears(100)
$secret = Read-Host -Prompt 'Enter App Secret Key ' -AsSecureString
$secPassword = ConvertTo-SecureString -AsPlainText -Force -String $secret
New-AzADAppCredential -ObjectId $myApp.ObjectId -StartDate $startDate -EndDate $endDate -Password $secPassword
$ResourceAppIdURI = "https://graph.windows.net/"
# $authority = "https://login.microsoftonline.com/$tenant/oauth2/v2.0/token"
$authority = "https://login.windows.net/$tenant/oauth2/token"
$ClientCred = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential" -ArgumentList $myApp.ApplicationId, $secret
$AuthContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority,$false
$AuthContext.TokenCache.Clear()
Start-Sleep -Seconds 10
$Token = $Authcontext.AcquireTokenAsync($ResourceAppIdURI, $ClientCred)
$AuthHeader = @{"Authorization" = $Token.Result.CreateAuthorizationHeader();"Content-Type"="application/json"}
$url = "https://graph.windows.net/$tenant/applications/$($myApp.ObjectID)?api-version=1.6"
Write-Host "URL: " $url
$postData = "{`"requiredResourceAccess`":[{`"resourceAppId`":`"00000003-0000-0000-c000-000000000000`",
`"resourceAccess`":[{`"id`":`"e1fe6dd8-ba31-4d61-89e7-88639da4683d`",`"type`":`"Scope`"}]}]}";
$result = Invoke-RestMethod -Uri $url -Method "PATCH" -Headers $AuthHeader -Body $postData
Write-Host "Result of App API permission: " $result
如果要调用 Azure AAD graph API 以使用 OAuth 2.0 客户端凭据流分配权限,我们需要提供足够的权限(Azure AD Graph -> Aapplication permissions -> Application.ReadWrite.All)
此外,关于如何使用PowerShell为AD应用程序分配权限,我们也可以使用PowerShell模块AzureAD。
例如
Connect-AzureAD
$AppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "00000003-0000-0000-c000-000000000000";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "";
Type = ""},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "";
Type = ""}
}
Set-AzureADApplication -ObjectId <the app object id> -RequiredResourceAccess $AppAccess
更新
根据我的测试,当我们使用Az模块时,我们可以使用以下方法获取访问令牌并调用AAD graph rest API。但请注意,当您使用该方法时,您使用的帐户 运行 Connect-AzAccount
应该是 Azure AD Global Admin
Connect-AzAccount
$context =Get-AzContext
$dexResourceUrl='https://graph.windows.net/'
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account,
$context.Environment,
$context.Tenant.Id.ToString(),
$null,
[Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never,
$null, $dexResourceUrl).AccessToken
# assign permissions
$headers =@{}
$headers.Add("Content-Type", "application/json")
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($token)")
$body = "{
`n `"requiredResourceAccess`": [{
`n `"resourceAppId`": `"00000003-0000-0000-c000-000000000000`",
`n `"resourceAccess`": [
`n {
`n `"id`": `"405a51b5-8d8d-430b-9842-8be4b0e9f324`",
`n `"type`": `"Role`"
`n },
`n {
`n `"id`": `"09850681-111b-4a89-9bed-3f2cae46d706`",
`n `"type`": `"Role`"
`n }
`n ]
`n }
`n ]
`n}
`n"
$url ='https://graph.windows.net/hanxia.onmicrosoft.com/applications/d4975420-841f-47d5-a3d2-0870901f13cd?api-version=1.6'
Invoke-RestMethod $url -Method 'PATCH' -Headers $headers -Body $body
#check if adding the permissions you need
$headers =@{}
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($token)")
$url ='https://graph.windows.net/hanxia.onmicrosoft.com/applications/<aad application object id>?api-version=1.6'
$response=Invoke-RestMethod $url -Method 'GET' -Headers $headers
$response.requiredResourceAccess | ConvertTo-Json
在我的例子中,最简单的方法是结合 Azure-powershell
模块和 Az cli
模块
所以,一旦我创建了我的新应用程序:
$myApp = New-AzADApplication -DisplayName $AppName -IdentifierUris "http://$AppName.com"
然后我将使用 Az Cli
登录到 azure,例如:
- 添加一些 api 权限
- 授予这些权限目录管理员同意(如果需要)
. { $azcliLogin = az login }
. { az account set --subscription $config.subscriptionId }
. { az ad app permission add --id $myApp.appid --api 00000002-0000-0000-c000-000000000000 --api-permissions 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175=Role }
. { $appApiGrant = az ad app permission grant --id $config.azureAccess.appid --api 00000002-0000-0000-c000-000000000000 }
. { az ad app permission admin-consent --id $myApp.appid }
其中:
--api 00000002-0000-0000-c000-000000000000
指 Microsoft Graph API
--api-permissions 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175=Role
指的是这个api上的一些角色,如Directory.ReadWrite.All
You can get the required API and API-PERMISSIONS guids from the App manifiest in Azure
通过这种方式,您可以在单个 powershell 脚本中创建具有所需授予 api 权限的应用程序。