Skip to content

Commit 337a508

Browse files
authored
Merge pull request #976 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents ab5e24b + 3f03634 commit 337a508

1 file changed

Lines changed: 116 additions & 99 deletions

File tree

Modules/CIPPCore/Public/Authentication/Initialize-CIPPAuth.ps1

Lines changed: 116 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ function Initialize-CIPPAuth {
77
Loads SAM credentials from Key Vault (or DevSecrets table),
88
auto-patches redirect URIs on the SAM and SSO app registrations,
99
and configures EasyAuth if SSO credentials are provisioned but
10-
EasyAuth is not yet enabled.
10+
EasyAuth is not yet enabled. On a fresh deployment with nothing
11+
configured, requests Craft's setup wizard mode.
1112
#>
1213
[CmdletBinding()]
1314
param()
@@ -19,26 +20,41 @@ function Initialize-CIPPAuth {
1920
NeedsSetup = $true
2021
}
2122

22-
# 1. Determine Key Vault name
23+
# -- Entry logging --
24+
$EasyAuthEnabled = [Craft.Services.AppLifecycleBridge]::IsEasyAuthConfigured()
25+
$IsDevStorage = ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') -or ($env:NonLocalHostAzurite -eq 'true')
2326
$KVName = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0]
2427

25-
# 2. Try loading SAM credentials
26-
if ($KVName -or $env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true' -or $env:NonLocalHostAzurite -eq 'true') {
28+
Write-Information "[Auth-Init] Starting — EasyAuth=$EasyAuthEnabled, DevStorage=$IsDevStorage, KVName='$KVName', DeploymentId='$env:WEBSITE_DEPLOYMENT_ID'"
29+
30+
# 1. Try loading SAM credentials
31+
if ($KVName -or $IsDevStorage) {
2732
$AuthState.HasKeyVault = [bool]$KVName
33+
Write-Information "[Auth-Init] Credential source available (KV=$($AuthState.HasKeyVault), DevStorage=$IsDevStorage) — attempting SAM load"
2834
try {
2935
$Auth = Get-CIPPAuthentication
3036
if ($Auth -and $env:ApplicationID -and $env:TenantID) {
3137
$AuthState.HasSAMCredentials = $true
3238
$AuthState.NeedsSetup = $false
3339
$AuthState.IsConfigured = $true
34-
Write-Information "[Auth-Init] SAM credentials loaded (AppID: $($env:ApplicationID))"
40+
Write-Information "[Auth-Init] SAM credentials loaded (AppID: $($env:ApplicationID), TenantID: $($env:TenantID))"
41+
} else {
42+
Write-Information '[Auth-Init] SAM credential load returned but env vars not populated — credentials not available yet (expected on fresh deployment)'
3543
}
3644
} catch {
37-
Write-Information "[Auth-Init] Could not load SAM credentials: $_"
45+
$ErrorMessage = "$_"
46+
# Distinguish "not found" from real access errors
47+
if ($ErrorMessage -match 'SecretNotFound|not found|does not exist|Development variables not set') {
48+
Write-Information "[Auth-Init] SAM credentials not found in storage — expected on fresh deployment"
49+
} else {
50+
Write-Information "[Auth-Init] ERROR accessing credential storage (possible permission/network issue): $ErrorMessage"
51+
}
3852
}
53+
} else {
54+
Write-Information '[Auth-Init] No credential source available — WEBSITE_DEPLOYMENT_ID is not set and not using dev storage. Cannot load SAM credentials.'
3955
}
4056

41-
# 3. Auto-patch redirect URIs if we have credentials
57+
# 2. Auto-patch redirect URIs if we have credentials
4258
if ($AuthState.HasSAMCredentials) {
4359
try {
4460
Update-CIPPSAMRedirectUri
@@ -53,13 +69,86 @@ function Initialize-CIPPAuth {
5369
}
5470
}
5571

56-
# 4. If EasyAuth is not configured, check for SSO credentials and set it up
57-
$EasyAuthEnabled = [Craft.Services.AppLifecycleBridge]::IsEasyAuthConfigured()
58-
if (-not $EasyAuthEnabled -and $AuthState.HasSAMCredentials) {
59-
# If the central migration app ID is set, configure EasyAuth with implicit auth
60-
# (no client secret). This lets the user log in via the shared app while the
61-
# ForcedSsoMigrationDialog guides them through creating their own CIPP-SSO app.
62-
# Once they complete migration, step 5 detects the clientId change and cleans up.
72+
# 3. Handle EasyAuth configuration based on current state
73+
if ($EasyAuthEnabled) {
74+
Write-Information '[Auth-Init] EasyAuth is already configured'
75+
76+
# 3a. If CIPP_SSO_MIGRATION_APPID is set, check if migration is complete
77+
if ($env:CIPP_SSO_MIGRATION_APPID) {
78+
Write-Information '[Auth-Init] EasyAuth is active but CIPP_SSO_MIGRATION_APPID still set — checking if migration is complete...'
79+
try {
80+
$AuthConfigJson = $env:WEBSITE_AUTH_V2_CONFIG_JSON
81+
if ($AuthConfigJson) {
82+
$AuthConfig = $AuthConfigJson | ConvertFrom-Json -ErrorAction Stop
83+
$ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
84+
85+
if ($ConfiguredAppId -eq $env:CIPP_SSO_MIGRATION_APPID) {
86+
Write-Information '[Auth-Init] EasyAuth clientId matches migration app — migration still pending'
87+
} elseif ($ConfiguredAppId) {
88+
Write-Information "[Auth-Init] EasyAuth clientId ($ConfiguredAppId) differs from migration app — migration complete, cleaning up"
89+
$Removed = Remove-CIPPMigrationAppSetting -SettingName 'CIPP_SSO_MIGRATION_APPID'
90+
if ($Removed) {
91+
[Craft.Services.AppLifecycleBridge]::RequestRestart('SSO migration env var cleaned up during warmup')
92+
}
93+
} else {
94+
Write-Information '[Auth-Init] No clientId found in EasyAuth config — skipping cleanup'
95+
}
96+
}
97+
} catch {
98+
Write-Information "[Auth-Init] Migration cleanup check failed (non-fatal): $_"
99+
}
100+
}
101+
102+
# 3b. Reconcile EasyAuth issuer with SSOMultiTenant setting
103+
if ($AuthState.HasSAMCredentials -and -not $env:CIPP_SSO_MIGRATION_APPID) {
104+
try {
105+
$AuthConfigJson = $env:WEBSITE_AUTH_V2_CONFIG_JSON
106+
if ($AuthConfigJson) {
107+
$AuthConfig = $AuthConfigJson | ConvertFrom-Json -ErrorAction Stop
108+
$CurrentIssuer = $AuthConfig.identityProviders.azureActiveDirectory.registration.openIdIssuer
109+
$ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
110+
111+
if ($CurrentIssuer -and $ConfiguredAppId) {
112+
$SSOMultiTenant = $false
113+
if ($IsDevStorage) {
114+
try {
115+
$DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets'
116+
$Secret = Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'SSO' and RowKey eq 'SSO'" -ErrorAction SilentlyContinue
117+
$SSOMultiTenant = $Secret.SSOMultiTenant -eq 'True'
118+
} catch { }
119+
} elseif ($KVName) {
120+
try {
121+
$MtVal = Get-CippKeyVaultSecret -VaultName $KVName -Name 'SSOMultiTenant' -AsPlainText -ErrorAction Stop
122+
$SSOMultiTenant = $MtVal -eq 'True'
123+
} catch { }
124+
}
125+
126+
$ExpectedIssuer = if ($SSOMultiTenant) {
127+
'https://login.microsoftonline.com/common/v2.0'
128+
} else {
129+
"https://login.microsoftonline.com/$($env:TenantID)/v2.0"
130+
}
131+
132+
if ($CurrentIssuer -ne $ExpectedIssuer) {
133+
Write-Information "[Auth-Init] EasyAuth issuer mismatch: current=$CurrentIssuer expected=$ExpectedIssuer — updating"
134+
$Configured = Set-CIPPSSOEasyAuth -AppId $ConfiguredAppId -MultiTenant $SSOMultiTenant -TenantId $env:TenantID
135+
if ($Configured) {
136+
Write-Information '[Auth-Init] EasyAuth issuer updated — requesting container restart'
137+
[Craft.Services.AppLifecycleBridge]::RequestRestart('EasyAuth issuer updated to match SSOMultiTenant setting during warmup')
138+
}
139+
} else {
140+
Write-Information "[Auth-Init] EasyAuth issuer matches SSOMultiTenant setting ($SSOMultiTenant) — no update needed"
141+
}
142+
}
143+
}
144+
} catch {
145+
Write-Information "[Auth-Init] EasyAuth issuer reconciliation failed (non-fatal): $_"
146+
}
147+
}
148+
} elseif ($AuthState.HasSAMCredentials) {
149+
# EasyAuth NOT configured but we DO have SAM credentials — try to auto-configure
150+
Write-Information '[Auth-Init] EasyAuth not configured but SAM credentials available — attempting auto-configuration'
151+
63152
if ($env:CIPP_SSO_MIGRATION_APPID) {
64153
Write-Information "[Auth-Init] CIPP_SSO_MIGRATION_APPID is set ($($env:CIPP_SSO_MIGRATION_APPID)) — configuring implicit auth EasyAuth"
65154
try {
@@ -74,12 +163,12 @@ function Initialize-CIPPAuth {
74163
return $AuthState
75164
}
76165

77-
Write-Information '[Auth-Init] EasyAuth not configured — checking for SSO credentials...'
166+
# Try to find SSO credentials and configure EasyAuth automatically
78167
try {
79168
$SSOAppId = $null
80169
$SSOMultiTenant = $false
81170

82-
if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true' -or $env:NonLocalHostAzurite -eq 'true') {
171+
if ($IsDevStorage) {
83172
$DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets'
84173
$Secret = Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'SSO' and RowKey eq 'SSO'" -ErrorAction SilentlyContinue
85174
$SSOAppId = $Secret.SSOAppId
@@ -100,95 +189,23 @@ function Initialize-CIPPAuth {
100189
[Craft.Services.AppLifecycleBridge]::RequestRestart('EasyAuth configured from SSO credentials during warmup')
101190
}
102191
} else {
103-
Write-Information '[Auth-Init] No SSO credentials found — enabling setup wizard'
104-
[Craft.Services.AppLifecycleBridge]::RequestSetupMode('No SSO credentials found — setup wizard needed for initial EasyAuth configuration')
192+
Write-Information '[Auth-Init] SAM credentials loaded but no SSO AppId found — enabling setup wizard'
193+
[Craft.Services.AppLifecycleBridge]::RequestSetupMode('SAM credentials available but no SSO app configured — setup wizard needed')
105194
}
106195
} catch {
107196
Write-Information "[Auth-Init] SSO EasyAuth setup failed (non-fatal): $_"
197+
[Craft.Services.AppLifecycleBridge]::RequestSetupMode('SSO setup failed — setup wizard needed for manual configuration')
108198
}
199+
} else {
200+
# No EasyAuth AND no SAM credentials — this is a fresh/unconfigured deployment
201+
Write-Information '[Auth-Init] Fresh deployment detected — no EasyAuth configured and no SAM credentials available'
202+
Write-Information '[Auth-Init] Requesting setup wizard mode for initial configuration'
203+
[Craft.Services.AppLifecycleBridge]::RequestSetupMode('Fresh deployment — no credentials or EasyAuth configured')
204+
$AuthState.NeedsSetup = $true
109205
}
110206

111-
# 5. Reconcile EasyAuth issuer with SSOMultiTenant setting: if EasyAuth is already
112-
# configured, check whether the issuer URL matches the current SSOMultiTenant value
113-
# from Key Vault. If it changed (e.g. toggled from single to multi-tenant), update
114-
# the EasyAuth config via ARM and restart.
115-
if ($EasyAuthEnabled -and $AuthState.HasSAMCredentials -and -not $env:CIPP_SSO_MIGRATION_APPID) {
116-
try {
117-
$AuthConfigJson = $env:WEBSITE_AUTH_V2_CONFIG_JSON
118-
if ($AuthConfigJson) {
119-
$AuthConfig = $AuthConfigJson | ConvertFrom-Json -ErrorAction Stop
120-
$CurrentIssuer = $AuthConfig.identityProviders.azureActiveDirectory.registration.openIdIssuer
121-
$ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
122-
123-
if ($CurrentIssuer -and $ConfiguredAppId) {
124-
# Read SSOMultiTenant from KV/DevSecrets
125-
$SSOMultiTenant = $false
126-
if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true' -or $env:NonLocalHostAzurite -eq 'true') {
127-
try {
128-
$DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets'
129-
$Secret = Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'SSO' and RowKey eq 'SSO'" -ErrorAction SilentlyContinue
130-
$SSOMultiTenant = $Secret.SSOMultiTenant -eq 'True'
131-
} catch { }
132-
} elseif ($KVName) {
133-
try {
134-
$MtVal = Get-CippKeyVaultSecret -VaultName $KVName -Name 'SSOMultiTenant' -AsPlainText -ErrorAction Stop
135-
$SSOMultiTenant = $MtVal -eq 'True'
136-
} catch { }
137-
}
138-
139-
$ExpectedIssuer = if ($SSOMultiTenant) {
140-
'https://login.microsoftonline.com/common/v2.0'
141-
} else {
142-
"https://login.microsoftonline.com/$($env:TenantID)/v2.0"
143-
}
144-
145-
if ($CurrentIssuer -ne $ExpectedIssuer) {
146-
Write-Information "[Auth-Init] EasyAuth issuer mismatch: current=$CurrentIssuer expected=$ExpectedIssuer — updating"
147-
$Configured = Set-CIPPSSOEasyAuth -AppId $ConfiguredAppId -MultiTenant $SSOMultiTenant -TenantId $env:TenantID
148-
if ($Configured) {
149-
Write-Information '[Auth-Init] EasyAuth issuer updated — requesting container restart'
150-
[Craft.Services.AppLifecycleBridge]::RequestRestart('EasyAuth issuer updated to match SSOMultiTenant setting during warmup')
151-
}
152-
} else {
153-
Write-Information "[Auth-Init] EasyAuth issuer matches SSOMultiTenant setting ($SSOMultiTenant) — no update needed"
154-
}
155-
}
156-
}
157-
} catch {
158-
Write-Information "[Auth-Init] EasyAuth issuer reconciliation failed (non-fatal): $_"
159-
}
160-
}
161-
162-
# 6. Post-migration cleanup: if CIPP_SSO_MIGRATION_APPID is still set but EasyAuth
163-
# is now configured, check whether the EasyAuth clientId still matches the migration
164-
# app. If it differs, the customer's own CIPP-SSO app is active and we can remove
165-
# the migration trigger env var.
166-
if ($EasyAuthEnabled -and $env:CIPP_SSO_MIGRATION_APPID) {
167-
Write-Information '[Auth-Init] EasyAuth is active but CIPP_SSO_MIGRATION_APPID still set — checking if migration is complete...'
168-
try {
169-
$AuthConfigJson = $env:WEBSITE_AUTH_V2_CONFIG_JSON
170-
if ($AuthConfigJson) {
171-
$AuthConfig = $AuthConfigJson | ConvertFrom-Json -ErrorAction Stop
172-
$ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
173-
174-
if ($ConfiguredAppId -eq $env:CIPP_SSO_MIGRATION_APPID) {
175-
# EasyAuth is still using the central migration app — migration not done yet
176-
Write-Information '[Auth-Init] EasyAuth clientId matches migration app — migration still pending'
177-
} elseif ($ConfiguredAppId) {
178-
# EasyAuth clientId differs from the migration app — customer's own app is active
179-
Write-Information "[Auth-Init] EasyAuth clientId ($ConfiguredAppId) differs from migration app — migration complete, cleaning up"
180-
$Removed = Remove-CIPPMigrationAppSetting -SettingName 'CIPP_SSO_MIGRATION_APPID'
181-
if ($Removed) {
182-
[Craft.Services.AppLifecycleBridge]::RequestRestart('SSO migration env var cleaned up during warmup')
183-
}
184-
} else {
185-
Write-Information '[Auth-Init] No clientId found in EasyAuth config — skipping cleanup'
186-
}
187-
}
188-
} catch {
189-
Write-Information "[Auth-Init] Migration cleanup check failed (non-fatal): $_"
190-
}
191-
}
207+
# -- Exit logging --
208+
Write-Information "[Auth-Init] Complete — IsConfigured=$($AuthState.IsConfigured), HasSAM=$($AuthState.HasSAMCredentials), NeedsSetup=$($AuthState.NeedsSetup), EasyAuth=$EasyAuthEnabled"
192209

193210
return $AuthState
194211
}

0 commit comments

Comments
 (0)