273 lines
10 KiB
PowerShell
273 lines
10 KiB
PowerShell
# MS Entra (Azure AD) Setup Script for Miracles In Motion (PowerShell)
|
|
# This script helps configure Azure AD authentication for the application
|
|
|
|
param(
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$AppName = "Miracles In Motion Web App",
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$Domain = "mim4u.org",
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$StaticWebAppName = "",
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$AzureResourceGroup = "rg-miraclesinmotion-prod",
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$KeyVaultName = ""
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Write-Host "🔐 MS Entra (Azure AD) Setup Script" -ForegroundColor Green
|
|
Write-Host "==========================================" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Check if Azure CLI is installed
|
|
if (-not (Get-Command "az" -ErrorAction SilentlyContinue)) {
|
|
Write-Host "❌ Azure CLI not found. Please install it first." -ForegroundColor Red
|
|
Write-Host "Install from: https://docs.microsoft.com/cli/azure/install-azure-cli" -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
|
|
# Check if logged in to Azure
|
|
Write-Host "📋 Checking Azure login status..." -ForegroundColor Cyan
|
|
$account = az account show --output json 2>$null | ConvertFrom-Json
|
|
if (-not $account) {
|
|
Write-Host "⚠️ Not logged in to Azure. Please log in..." -ForegroundColor Yellow
|
|
az login
|
|
$account = az account show --output json | ConvertFrom-Json
|
|
}
|
|
Write-Host "✅ Logged in as: $($account.user.name)" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Get Azure Static Web App URL
|
|
Write-Host "📋 Getting Azure Static Web App information..." -ForegroundColor Cyan
|
|
|
|
if ([string]::IsNullOrEmpty($StaticWebAppName)) {
|
|
# Try to find Static Web App
|
|
$swa = az staticwebapp list --resource-group $AzureResourceGroup --output json | ConvertFrom-Json | Select-Object -First 1
|
|
if ($swa) {
|
|
$StaticWebAppName = $swa.name
|
|
}
|
|
}
|
|
|
|
$azureStaticWebAppUrl = ""
|
|
if (-not [string]::IsNullOrEmpty($StaticWebAppName)) {
|
|
$azureStaticWebAppUrl = az staticwebapp show `
|
|
--name $StaticWebAppName `
|
|
--resource-group $AzureResourceGroup `
|
|
--query "defaultHostname" -o tsv 2>$null
|
|
|
|
if ($azureStaticWebAppUrl) {
|
|
$azureStaticWebAppUrl = "https://$azureStaticWebAppUrl"
|
|
Write-Host "✅ Static Web App URL: $azureStaticWebAppUrl" -ForegroundColor Green
|
|
}
|
|
} else {
|
|
Write-Host "⚠️ Static Web App not found. Using default URL format." -ForegroundColor Yellow
|
|
$azureStaticWebAppUrl = "https://${StaticWebAppName}.azurestaticapps.net"
|
|
}
|
|
|
|
$productionUrl = "https://$Domain"
|
|
$wwwUrl = "https://www.$Domain"
|
|
|
|
Write-Host ""
|
|
|
|
# Get Tenant ID
|
|
$tenantId = $account.tenantId
|
|
Write-Host "✅ Tenant ID: $tenantId" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Check if app registration already exists
|
|
Write-Host "🔍 Checking for existing app registration..." -ForegroundColor Cyan
|
|
$existingApp = az ad app list --display-name $AppName --output json | ConvertFrom-Json | Select-Object -First 1
|
|
|
|
if ($existingApp) {
|
|
Write-Host "⚠️ App registration already exists: $($existingApp.appId)" -ForegroundColor Yellow
|
|
$updateApp = Read-Host "Do you want to update it? (y/n)"
|
|
if ($updateApp -ne "y") {
|
|
$appId = $existingApp.appId
|
|
Write-Host "✅ Using existing app registration" -ForegroundColor Green
|
|
} else {
|
|
$appId = $existingApp.appId
|
|
Write-Host "📝 Updating app registration..." -ForegroundColor Cyan
|
|
}
|
|
} else {
|
|
# Create app registration
|
|
Write-Host "📝 Creating app registration..." -ForegroundColor Cyan
|
|
$appId = az ad app create `
|
|
--display-name $AppName `
|
|
--sign-in-audience "AzureADMultipleOrgs" `
|
|
--web-redirect-uris $productionUrl $wwwUrl $azureStaticWebAppUrl `
|
|
--query "appId" -o tsv
|
|
|
|
Write-Host "✅ App registration created: $appId" -ForegroundColor Green
|
|
}
|
|
|
|
Write-Host ""
|
|
|
|
# Update redirect URIs
|
|
Write-Host "📝 Updating redirect URIs..." -ForegroundColor Cyan
|
|
az ad app update --id $appId `
|
|
--web-redirect-uris $productionUrl $wwwUrl $azureStaticWebAppUrl `
|
|
--enable-id-token-issuance true `
|
|
--enable-access-token-issuance false | Out-Null
|
|
|
|
Write-Host "✅ Redirect URIs updated" -ForegroundColor Green
|
|
Write-Host " - $productionUrl"
|
|
Write-Host " - $wwwUrl"
|
|
Write-Host " - $azureStaticWebAppUrl"
|
|
Write-Host ""
|
|
|
|
# Configure API permissions
|
|
Write-Host "📝 Configuring API permissions..." -ForegroundColor Cyan
|
|
|
|
$graphPermissions = @(
|
|
"User.Read",
|
|
"User.ReadBasic.All",
|
|
"email",
|
|
"openid",
|
|
"profile"
|
|
)
|
|
|
|
foreach ($permission in $graphPermissions) {
|
|
Write-Host " Adding permission: $permission" -ForegroundColor Gray
|
|
$permissionId = az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?value=='$permission'].id" -o tsv
|
|
if ($permissionId) {
|
|
az ad app permission add `
|
|
--id $appId `
|
|
--api "00000003-0000-0000-c000-000000000000" `
|
|
--api-permissions "${permissionId}=Scope" 2>$null | Out-Null
|
|
}
|
|
}
|
|
|
|
Write-Host "✅ API permissions configured" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Create service principal
|
|
Write-Host "📝 Creating service principal..." -ForegroundColor Cyan
|
|
$spId = az ad sp create --id $appId --query "id" -o tsv 2>$null
|
|
if (-not $spId) {
|
|
$spId = az ad sp show --id $appId --query "id" -o tsv
|
|
}
|
|
|
|
Write-Host "✅ Service principal created: $spId" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
# Grant admin consent
|
|
Write-Host "📝 Granting admin consent for API permissions..." -ForegroundColor Cyan
|
|
$hasAdmin = Read-Host "Do you have admin privileges to grant consent? (y/n)"
|
|
|
|
if ($hasAdmin -eq "y") {
|
|
az ad app permission admin-consent --id $appId 2>$null
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "✅ Admin consent granted" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "⚠️ Could not grant admin consent. You may need to do this manually." -ForegroundColor Yellow
|
|
Write-Host " Go to: Azure Portal → Microsoft Entra ID → App registrations → $AppName → API permissions → Grant admin consent" -ForegroundColor Yellow
|
|
}
|
|
} else {
|
|
Write-Host "⚠️ Skipping admin consent. Please grant consent manually in Azure Portal." -ForegroundColor Yellow
|
|
Write-Host " Go to: Azure Portal → Microsoft Entra ID → App registrations → $AppName → API permissions → Grant admin consent" -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
|
|
# Create client secret
|
|
Write-Host "📝 Client Secret Configuration..." -ForegroundColor Cyan
|
|
$createSecret = Read-Host "Do you want to create a client secret? (y/n)"
|
|
|
|
$clientSecret = ""
|
|
if ($createSecret -eq "y") {
|
|
$secretName = "Miracles In Motion Secret $(Get-Date -Format 'yyyyMMdd')"
|
|
$clientSecret = az ad app credential reset --id $appId --display-name $secretName --years 2 --query "password" -o tsv
|
|
Write-Host "✅ Client secret created" -ForegroundColor Green
|
|
Write-Host "⚠️ IMPORTANT: Save this secret now - it won't be shown again!" -ForegroundColor Red
|
|
Write-Host "Secret: $clientSecret" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
Read-Host "Press Enter to continue after saving the secret..."
|
|
} else {
|
|
Write-Host "⚠️ Skipping client secret creation" -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
|
|
# Store configuration in Key Vault
|
|
Write-Host "📝 Storing configuration in Key Vault..." -ForegroundColor Cyan
|
|
|
|
if ([string]::IsNullOrEmpty($KeyVaultName)) {
|
|
$KeyVaultName = az keyvault list --resource-group $AzureResourceGroup --query "[0].name" -o tsv 2>$null
|
|
}
|
|
|
|
if ($KeyVaultName) {
|
|
Write-Host "Storing in Key Vault: $KeyVaultName" -ForegroundColor Gray
|
|
|
|
az keyvault secret set --vault-name $KeyVaultName --name "azure-client-id" --value $appId 2>$null | Out-Null
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "✅ Client ID stored" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "⚠️ Could not store Client ID" -ForegroundColor Yellow
|
|
}
|
|
|
|
az keyvault secret set --vault-name $KeyVaultName --name "azure-tenant-id" --value $tenantId 2>$null | Out-Null
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "✅ Tenant ID stored" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "⚠️ Could not store Tenant ID" -ForegroundColor Yellow
|
|
}
|
|
|
|
if ($clientSecret) {
|
|
az keyvault secret set --vault-name $KeyVaultName --name "azure-client-secret" --value $clientSecret 2>$null | Out-Null
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "✅ Client Secret stored" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "⚠️ Could not store Client Secret" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "⚠️ Key Vault not found. Skipping secret storage." -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
|
|
# Summary
|
|
Write-Host "✅ MS Entra Setup Complete!" -ForegroundColor Green
|
|
Write-Host "==================================" -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "Configuration Summary:"
|
|
Write-Host " App Registration ID: $appId"
|
|
Write-Host " Tenant ID: $tenantId"
|
|
Write-Host " Service Principal ID: $spId"
|
|
Write-Host ""
|
|
Write-Host "Redirect URIs:"
|
|
Write-Host " - $productionUrl"
|
|
Write-Host " - $wwwUrl"
|
|
Write-Host " - $azureStaticWebAppUrl"
|
|
Write-Host ""
|
|
Write-Host "Next Steps:"
|
|
Write-Host "1. Assign users to app roles in Azure Portal"
|
|
Write-Host "2. Update staticwebapp.config.json with authentication configuration"
|
|
Write-Host "3. Update application code to use Azure AD authentication"
|
|
Write-Host "4. Test authentication flow"
|
|
Write-Host ""
|
|
Write-Host "Azure Portal Links:"
|
|
Write-Host " App Registration: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/$appId"
|
|
Write-Host " API Permissions: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnAPI/appId/$appId"
|
|
Write-Host ""
|
|
|
|
# Export variables
|
|
$configContent = @"
|
|
# Azure AD Configuration
|
|
AZURE_CLIENT_ID=$appId
|
|
AZURE_TENANT_ID=$tenantId
|
|
AZURE_CLIENT_SECRET=$clientSecret
|
|
AZURE_STATIC_WEB_APP_URL=$azureStaticWebAppUrl
|
|
AZURE_PRODUCTION_URL=$productionUrl
|
|
"@
|
|
|
|
$configContent | Out-File -FilePath ".azure-entra-config.env" -Encoding UTF8
|
|
Write-Host "✅ Configuration saved to .azure-entra-config.env" -ForegroundColor Green
|
|
Write-Host ""
|
|
|