Add PublicClientApplication script
This commit is contained in:
194
scripts/New-PublicClientApplication.ps1
Normal file
194
scripts/New-PublicClientApplication.ps1
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Alias("n")]
|
||||||
|
[string]$AppName,
|
||||||
|
[switch]$UsePowershellModules,
|
||||||
|
[Alias("h")]
|
||||||
|
[switch]$Help
|
||||||
|
)
|
||||||
|
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
function Show-Usage {
|
||||||
|
Write-Host "Usage: ./New-PublicClientApplication.ps1 -AppName <name>"
|
||||||
|
Write-Host "Options:"
|
||||||
|
Write-Host " -AppName, -n <name> Application display name (required)"
|
||||||
|
Write-Host " -UsePowershellModules Use Az.Accounts/Az.Resources cmdlets instead of Azure CLI"
|
||||||
|
Write-Host " -Help, -h Show this help message and exit"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-RequiredResourceAccess {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$M365GraphAppId,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$M365GraphScopeId,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$AzureDevOpsAppId,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$AzureDevOpsScopeId,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$AzureServiceMgmtAppId,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$AzureServiceMgmtScopeId
|
||||||
|
)
|
||||||
|
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
resourceAppId = $M365GraphAppId
|
||||||
|
resourceAccess = @(
|
||||||
|
@{
|
||||||
|
id = $M365GraphScopeId
|
||||||
|
type = "Scope"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
resourceAppId = $AzureDevOpsAppId
|
||||||
|
resourceAccess = @(
|
||||||
|
@{
|
||||||
|
id = $AzureDevOpsScopeId
|
||||||
|
type = "Scope"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
resourceAppId = $AzureServiceMgmtAppId
|
||||||
|
resourceAccess = @(
|
||||||
|
@{
|
||||||
|
id = $AzureServiceMgmtScopeId
|
||||||
|
type = "Scope"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Help) {
|
||||||
|
Show-Usage
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($AppName)) {
|
||||||
|
Write-Error "Application name is required."
|
||||||
|
Show-Usage
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$m365GraphAppId = "00000003-0000-0000-c000-000000000000"
|
||||||
|
$m365GraphScopeId = "0e263e50-5827-48a4-b97c-d940288653c7"
|
||||||
|
$azureServiceMgmtAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013"
|
||||||
|
$azureServiceMgmtScopeId = "41094075-9dad-400e-a0bd-54e686782033"
|
||||||
|
$azureDevOpsAppId = "499b84ac-1321-427f-aa17-267ca6975798"
|
||||||
|
$azureDevOpsScopeId = "ee69721e-6c3a-468f-a9ec-302d16a4c599"
|
||||||
|
|
||||||
|
if ($UsePowershellModules) {
|
||||||
|
if (-not (Get-Command Get-AzADApplication -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "Get-AzADApplication cmdlet not found. Install Az.Resources."
|
||||||
|
}
|
||||||
|
if (-not (Get-Command New-AzADApplication -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "New-AzADApplication cmdlet not found. Install Az.Resources."
|
||||||
|
}
|
||||||
|
if (-not (Get-Command Update-AzADApplication -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "Update-AzADApplication cmdlet not found. Install Az.Resources."
|
||||||
|
}
|
||||||
|
|
||||||
|
$azContext = Get-AzContext
|
||||||
|
if ($null -eq $azContext) {
|
||||||
|
throw "No Azure context found. Run Connect-AzAccount first."
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingApp = Get-AzADApplication -DisplayName $AppName -First 1
|
||||||
|
if ($null -ne $existingApp) {
|
||||||
|
Write-Error "Application '$AppName' already exists."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$requiredResourceAccess = Get-RequiredResourceAccess `
|
||||||
|
-M365GraphAppId $m365GraphAppId `
|
||||||
|
-M365GraphScopeId $m365GraphScopeId `
|
||||||
|
-AzureDevOpsAppId $azureDevOpsAppId `
|
||||||
|
-AzureDevOpsScopeId $azureDevOpsScopeId `
|
||||||
|
-AzureServiceMgmtAppId $azureServiceMgmtAppId `
|
||||||
|
-AzureServiceMgmtScopeId $azureServiceMgmtScopeId
|
||||||
|
|
||||||
|
$webConfig = @{
|
||||||
|
implicitGrantSettings = @{
|
||||||
|
enableAccessTokenIssuance = $true
|
||||||
|
enableIdTokenIssuance = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create first to obtain appId needed for msal<appId>://auth redirect URI.
|
||||||
|
$newApp = New-AzADApplication `
|
||||||
|
-DisplayName $AppName `
|
||||||
|
-SignInAudience "AzureADMyOrg" `
|
||||||
|
-IsFallbackPublicClient `
|
||||||
|
-PublicClientRedirectUri @("http://localhost") `
|
||||||
|
-RequiredResourceAccess $requiredResourceAccess `
|
||||||
|
-Web $webConfig
|
||||||
|
|
||||||
|
if ($null -eq $newApp -or [string]::IsNullOrWhiteSpace($newApp.AppId)) {
|
||||||
|
throw "Failed to create application '$AppName' via Az.Resources."
|
||||||
|
}
|
||||||
|
|
||||||
|
$appId = $newApp.AppId
|
||||||
|
|
||||||
|
Update-AzADApplication `
|
||||||
|
-ApplicationId $appId `
|
||||||
|
-SignInAudience "AzureADMyOrg" `
|
||||||
|
-IsFallbackPublicClient `
|
||||||
|
-RequiredResourceAccess $requiredResourceAccess `
|
||||||
|
-PublicClientRedirectUri @("http://localhost", "msal${appId}://auth") `
|
||||||
|
-Web $webConfig | Out-Null
|
||||||
|
} else {
|
||||||
|
# Find the app by name
|
||||||
|
$existingAppId = az ad app list --display-name $AppName --query "[0].appId" -o tsv
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Failed to query existing applications."
|
||||||
|
}
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($existingAppId)) {
|
||||||
|
Write-Error "Application '$AppName' already exists."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the app
|
||||||
|
$appId = az ad app create --display-name $AppName --query "appId" -o tsv
|
||||||
|
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($appId)) {
|
||||||
|
throw "Failed to create application '$AppName'."
|
||||||
|
}
|
||||||
|
|
||||||
|
$requiredResourceAccess = Get-RequiredResourceAccess `
|
||||||
|
-M365GraphAppId $m365GraphAppId `
|
||||||
|
-M365GraphScopeId $m365GraphScopeId `
|
||||||
|
-AzureDevOpsAppId $azureDevOpsAppId `
|
||||||
|
-AzureDevOpsScopeId $azureDevOpsScopeId `
|
||||||
|
-AzureServiceMgmtAppId $azureServiceMgmtAppId `
|
||||||
|
-AzureServiceMgmtScopeId $azureServiceMgmtScopeId | ConvertTo-Json -Depth 10 -Compress
|
||||||
|
|
||||||
|
$publicClientRedirectUris = @(
|
||||||
|
"http://localhost",
|
||||||
|
"msal${appId}://auth"
|
||||||
|
) | ConvertTo-Json -Compress
|
||||||
|
|
||||||
|
# Configure app to match "Azure Node Playground Public".
|
||||||
|
az ad app update `
|
||||||
|
--id $appId `
|
||||||
|
--set `
|
||||||
|
"signInAudience=AzureADMyOrg" `
|
||||||
|
"isFallbackPublicClient=true" `
|
||||||
|
"requiredResourceAccess=$requiredResourceAccess" `
|
||||||
|
"publicClient.redirectUris=$publicClientRedirectUris" `
|
||||||
|
"web.implicitGrantSettings.enableAccessTokenIssuance=true" `
|
||||||
|
"web.implicitGrantSettings.enableIdTokenIssuance=true" | Out-Null
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Failed to configure application '$AppName'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Created application '$AppName'"
|
||||||
|
Write-Host "appId: $appId"
|
||||||
Reference in New Issue
Block a user