43
43
This optional parameter allows you to provide Azure environment
44
44
. PARAMETER AzureApplicationName
45
45
This optional parameter allows you to provide Azure application name
46
+ . PARAMETER CertificateThumbprint
47
+ This optional parameter allows you to provide a certificate thumbprint to use the Azure application created by the script
48
+ . PARAMETER AppId
49
+ This optional parameter allows you to provide the AppId of the Azure application created by the script
50
+ . PARAMETER Organization
51
+ This optional parameter allows you to provide the organization name e.g., contoso.onmicrosoft.com
46
52
. PARAMETER EWSOnlineURL
47
53
This optional parameter allows you to provide EWS online url
48
54
. PARAMETER EWSOnlineScope
@@ -130,6 +136,18 @@ param(
130
136
[Parameter (Mandatory = $false , ParameterSetName = " Cleanup" )]
131
137
[String ]$AzureApplicationName = " CVE-2023-23397Application" ,
132
138
139
+ [Parameter (Mandatory = $false , ParameterSetName = " Audit" )]
140
+ [Parameter (Mandatory = $false , ParameterSetName = " Cleanup" )]
141
+ [String ]$CertificateThumbprint ,
142
+
143
+ [Parameter (Mandatory = $false , ParameterSetName = " Audit" )]
144
+ [Parameter (Mandatory = $false , ParameterSetName = " Cleanup" )]
145
+ [String ]$AppId ,
146
+
147
+ [Parameter (Mandatory = $false , ParameterSetName = " Audit" )]
148
+ [Parameter (Mandatory = $false , ParameterSetName = " Cleanup" )]
149
+ [String ]$Organization ,
150
+
133
151
[Parameter (Mandatory = $false , ParameterSetName = " Audit" )]
134
152
[Parameter (Mandatory = $false , ParameterSetName = " Cleanup" )]
135
153
[Uri ]$EWSOnlineURL = " https://outlook.office365.com/EWS/Exchange.asmx" ,
@@ -227,6 +245,7 @@ begin {
227
245
. $PSScriptRoot \..\..\..\Shared\Get-NuGetPackage.ps1
228
246
. $PSScriptRoot \..\..\..\Shared\Invoke-ExtractArchive.ps1
229
247
. $PSScriptRoot \..\..\..\Shared\LoggerFunctions.ps1
248
+ . $PSScriptRoot \..\..\..\Shared\AzureFunctions\Get-NewJsonWebToken.ps1
230
249
. $PSScriptRoot \..\..\..\Shared\Show-Disclaimer.ps1
231
250
232
251
$loggerParams = @ {
@@ -400,15 +419,22 @@ begin {
400
419
[string ]$ClientID ,
401
420
[string ]$AppSecret ,
402
421
[string ]$AzureADEndpoint ,
422
+ [bool ]$UseCertificateToAuthenticate = $false ,
403
423
[string ]$Scope
404
424
)
405
425
406
426
try {
407
427
$body = @ {
408
- scope = $Scope
409
- client_id = $ClientID
410
- client_secret = $AppSecret
411
- grant_type = " client_credentials"
428
+ scope = $Scope
429
+ client_id = $ClientID
430
+ grant_type = " client_credentials"
431
+ }
432
+
433
+ if ($UseCertificateToAuthenticate ) {
434
+ $body.Add (" client_assertion_type" , " urn:ietf:params:oauth:client-assertion-type:jwt-bearer" )
435
+ $body.Add (" client_assertion" , $AppSecret )
436
+ } else {
437
+ $body.Add (" client_secret" , $AppSecret )
412
438
}
413
439
414
440
$PostSplat = @ {
@@ -456,7 +482,8 @@ begin {
456
482
function GetApplicationDetails {
457
483
param (
458
484
$AzureApplicationName ,
459
- $AzureEnvironmentName
485
+ $AzureEnvironmentName ,
486
+ $UseCertificateToAuthenticate = $false
460
487
)
461
488
462
489
ConnectAzureAD - AzureEnvironmentName $AzureEnvironmentName
@@ -473,18 +500,22 @@ begin {
473
500
exit
474
501
}
475
502
476
- # Assign App Password, make it valid for 7 days
477
- $appPassword = New-AzureADApplicationPasswordCredential - ObjectId $aadApplication.ObjectId - CustomKeyIdentifier " AppAccessKey" - EndDate (Get-Date ).AddDays(7 ) - ErrorAction Stop
503
+ $returnObject = @ {
504
+ TenantID = (Get-AzureADTenantDetail ).ObjectId
505
+ ClientID = $aadApplication.AppId
506
+ }
478
507
479
- Write-Host " `n Waiting 60 seconds for app credentials to register.. "
480
- Start-Sleep - Seconds 60
481
- Write-Host " `n Continuing... "
508
+ if ( $UseCertificateToAuthenticate -ne $true ) {
509
+ # Assign App Password, make it valid for 7 days
510
+ $appPassword = New-AzureADApplicationPasswordCredential - ObjectId $aadApplication .ObjectId - CustomKeyIdentifier " AppAccessKey " - EndDate ( Get-Date ).AddDays( 7 ) - ErrorAction Stop
482
511
483
- return @ {
484
- " TenantID " = ( Get-AzureADTenantDetail ).ObjectId
485
- " ClientID " = $aadApplication .AppId
486
- " AppSecret" = $appPassword.Value
512
+ Write-Host " `n Waiting 60 seconds for app credentials to register... "
513
+ Start-Sleep - Seconds 60
514
+ Write-Host " `n Continuing... "
515
+ $returnObject .Add ( " AppSecret" , $appPassword.Value )
487
516
}
517
+
518
+ return $returnObject
488
519
}
489
520
490
521
# # function to delete Azure AD application
@@ -628,7 +659,36 @@ begin {
628
659
629
660
# if token is going to expire in next 5 min then refresh it
630
661
if ($null -eq $script :tokenLastRefreshTime -or $script :tokenLastRefreshTime.AddMinutes (55 ) -lt (Get-Date )) {
631
- $token.Value = CreateOAUTHToken - TenantID $applicationInfo.TenantID - ClientID $applicationInfo.ClientID - AppSecret $applicationInfo.AppSecret - AzureADEndpoint $AzureADEndpoint - Scope $EWSOnlineScope
662
+ $createOAuthTokenParams = @ {
663
+ TenantID = $applicationInfo.TenantID
664
+ ClientID = $applicationInfo.ClientID
665
+ AzureADEndpoint = $AzureADEndpoint
666
+ UseCertificateToAuthenticate = (-not ([System.String ]::IsNullOrEmpty($applicationInfo.CertificateThumbprint )))
667
+ Scope = $EWSOnlineScope
668
+ }
669
+
670
+ # Check if we use an app secret or certificate by using regex to match Json Web Token (JWT)
671
+ if ($applicationInfo.AppSecret -match " ^([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_\-\+\/=]*)" ) {
672
+ $jwtParams = @ {
673
+ CertificateThumbprint = $applicationInfo.CertificateThumbprint
674
+ CertificateStore = " CurrentUser"
675
+ Issuer = $applicationInfo.ClientID
676
+ Audience = (" {0}{1}/oauth2/v2.0/token" -f $AzureADEndpoint , $applicationInfo.TenantID )
677
+ Subject = $applicationInfo.ClientID
678
+ }
679
+ $jwt = Get-NewJsonWebToken @jwtParams
680
+
681
+ if ($null -eq $jwt ) {
682
+ Write-Host " Unable to sign a new Json Web Token by using certificate: $ ( $applicationInfo.CertificateThumbprint ) " - ForegroundColor Red
683
+ exit
684
+ }
685
+
686
+ $createOAuthTokenParams.Add (" AppSecret" , $jwt )
687
+ } else {
688
+ $createOAuthTokenParams.Add (" AppSecret" , $applicationInfo.AppSecret )
689
+ }
690
+
691
+ $token.Value = CreateOAUTHToken @createOAuthTokenParams
632
692
$ewsService.Value = EWSAuth - Environment $Environment - token $token.Value - EWSOnlineURL $EWSOnlineURL
633
693
}
634
694
}
@@ -806,16 +866,61 @@ begin {
806
866
}
807
867
808
868
if ($Environment -eq " Online" ) {
809
- $application = GetApplicationDetails - AzureApplicationName $AzureApplicationName - AzureEnvironmentName $AzureEnvironmentName
869
+ $getApplicationDetailsParams = @ {
870
+ AzureApplicationName = $AzureApplicationName
871
+ AzureEnvironmentName = $AzureEnvironmentName
872
+ UseCertificateToAuthenticate = (-not ([System.String ]::IsNullOrEmpty($CertificateThumbprint )))
873
+ }
874
+
875
+ if (([System.String ]::IsNullOrEmpty($AppId )) -or
876
+ ([System.String ]::IsNullOrEmpty($Organization )) -or
877
+ ([System.String ]::IsNullOrEmpty($CertificateThumbprint ))) {
878
+ $application = GetApplicationDetails @getApplicationDetailsParams
879
+
880
+ $TenantID = $application.Tenant.Id
881
+ $ClientID = $application.ClientID
882
+ } else {
883
+ $TenantID = $Organization
884
+ $ClientID = $AppId
885
+ }
810
886
811
887
$applicationInfo = @ {
812
- " TenantID" = $application.Tenant.Id
813
- " ClientID" = $application.ClientID
814
- " AppSecret" = $application.AppSecret
888
+ " TenantID" = $TenantID
889
+ " ClientID" = $ClientID
890
+ }
891
+
892
+ if ($null -ne $application.AppSecret ) {
893
+ $applicationInfo.Add (" AppSecret" , $application.AppSecret )
894
+ } else {
895
+ $jwtParams = @ {
896
+ CertificateThumbprint = $CertificateThumbprint
897
+ CertificateStore = " CurrentUser"
898
+ Issuer = $ClientID
899
+ Audience = (" {0}{1}/oauth2/v2.0/token" -f $AzureADEndpoint , $TenantID )
900
+ Subject = $ClientID
901
+ }
902
+ $jwt = Get-NewJsonWebToken @jwtParams
903
+
904
+ if ($null -eq $jwt ) {
905
+ Write-Host " Unable to generate Json Web Token by using certificate: $CertificateThumbprint " - ForegroundColor Red
906
+ exit
907
+ }
908
+
909
+ $applicationInfo.Add (" AppSecret" , $jwt )
910
+ $applicationInfo.Add (" CertificateThumbprint" , $CertificateThumbprint )
911
+ }
912
+
913
+ $createOAuthTokenParams = @ {
914
+ TenantID = $TenantID
915
+ ClientID = $ClientID
916
+ AppSecret = $applicationInfo.AppSecret
917
+ Scope = $EWSOnlineScope
918
+ AzureADEndpoint = $AzureADEndpoint
919
+ UseCertificateToAuthenticate = (-not ([System.String ]::IsNullOrEmpty($CertificateThumbprint )))
815
920
}
816
921
817
922
# Create OAUTH token
818
- $EWSToken = CreateOAUTHToken - TenantID $applicationInfo .TenantID - ClientID $applicationInfo .ClientID - AppSecret $applicationInfo .AppSecret - Scope $EWSOnlineScope - AzureADEndpoint $AzureADEndpoint
923
+ $EWSToken = CreateOAUTHToken @createOAuthTokenParams
819
924
820
925
$ewsService = EWSAuth - Environment $Environment - Token $EWSToken - EWSOnlineURL $EWSOnlineURL
821
926
} else {
0 commit comments