...
- Diese Schritte erfolgen in PowerShell, mit einem eigens zu installierenden PowerShell-Applet namens "ExchangeOnlineManagement"
- Hiermit wird das Recht vergeben, dass man mit dem clientsecret Zugriff auf die targetMailbox hat.
Testen mit Powershell
Die Angaben in spitzen Klammern (<...>) müssen durch die ermittelten/relevanten Werte ersetzt werden.
Applet Get-IMAPAccessToken.ps1
Code Block | ||
---|---|---|
| ||
Get-IMAPAccessToken.ps1 -tenantID "<tenantID>" -clientId "<clientID>" -clientsecret "<clientsecret>" -targetMailbox "<targetmailbox>" -verbose |
Testscript
...
language | powershell |
---|---|
collapse | true |
...
Anchor | ||||
---|---|---|---|---|
|
Die Powershell-App MSAL.PS ist ein Wrapper für MSAL.NET, der es ermöglicht, die Befehle aus Powershell zu rufen.
Diese App wird nicht von Microsoft gepflegt, sie ist ein Gitub-Projekt: https://github.com/
...
AzureAD/MSAL.PS/tree/master/src
Installation von MSAL.PS
1. Powershell als Administator aufrufen
2. Installationsbefehl eingeben
Install-Module -Name MSAL.PS
Testen mit Powershell
Die Angaben in spitzen Klammern (<...>) müssen durch die ermittelten/relevanten Werte ersetzt werden.
Mit Get-IMAPAccessToken.PS1
1. Sicherstellen, dass der Powershell-wrapper MSAL.PS auf dem PC installiert ist (siehe vorheriges Kapitel)
2. Die Datei Get-IMAPAccessToken.ps1 in einem beliebigen Verzeichnis ablegen (z.B. in C:\TEMP)
3. Die Werte ermitteln für
- tenantID
- clientID
- clientsecret
- targetmailbox
4. Powershell öffnen und das Skript aufrufen - dabei natürlich die <..>-Variablen durch die richtigen Werte ersetzen
Code Block | ||||
---|---|---|---|---|
| ||||
cd \ cd Temp .\Get-IMAPAccessToken.ps1 -tenantID "<tenantID>" -clientId "<clientID>" -clientsecret "<clientsecret>" -targetMailbox "<targetMailbox>" -Verbose #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)][string]$tenantID, [Parameter(Mandatory = $true)][String]$clientId, [Parameter(Mandatory = $true,ParameterSetName="authorizationcode")][String]$redirectUri, [Parameter(Mandatory = $true,ParameterSetName="authorizationcode")][String]$LoginHint, [Parameter(Mandatory = $false,ParameterSetName="authorizationcode")][String]$SharedMailbox, [Parameter(Mandatory = $true,ParameterSetName="clientcredentialsSecret")][String]$clientsecret, [Parameter(Mandatory = $true,ParameterSetName="clientcredentialsCertificate")][String]$clientcertificate, [Parameter(Mandatory = $true,ParameterSetName="clientcredentialsSecret")] [Parameter(Mandatory = $true,ParameterSetName="clientcredentialsCertificate")] [String]$targetMailbox ) function Test-IMAPXOAuth2Connectivity { # get Accesstoken via user authentication and store Access+Refreshtoken for next attempts if ( $redirectUri ){ $MsftPowerShellClient = New-MsalClientApplication -ClientId $clientID -TenantId $tenantID -RedirectUri $redirectURI | Enable-MsalTokenCacheOnDisk -PassThru try { $authResult = $MsftPowerShellClient | Get-MsalToken -LoginHint $LoginHint -Scopes 'https://outlook.office365.com/.default' } catch { Write-Host "Ran into an exception while getting accesstoken user grant flow" -ForegroundColor Red $_.Exception.Message $_.FullyQualifiedErrorId break } } if ( $clientsecret ){ $SecuredclientSecret = ConvertTo-SecureString $clientsecret -AsPlainText -Force $MsftPowerShellClient = New-MsalClientApplication -ClientId $clientID -TenantId $tenantID -ClientSecret $SecuredclientSecret try { $authResult = $MsftPowerShellClient | Get-MsalToken -Scopes 'https://outlook.office365.com/.default' } catch { Write-Host "Ran into an exception while getting accesstoken using clientsecret" -ForegroundColor Red $_.Exception.Message $_.FullyQualifiedErrorId break } } if ( $clientcertificate ){ $ClientCert = Get-ChildItem "cert:\currentuser\my\$clientcertificate" $MsftPowerShellClient = New-MsalClientApplication -ClientId $clientID -TenantId $tenantID -ClientCertificate $ClientCert try { $authResult = $MsftPowerShellClient | Get-MsalToken -Scopes 'https://outlook.office365.com/.default' } catch { Write-Host "Ran into an exception while getting accesstoken using certificate" -ForegroundColor Red $_.Exception.Message $_.FullyQualifiedErrorId break } } $accessToken = $authResult.AccessToken Write-Verbose "Access Token -- $accessToken" $userName = $authResult.Account.Username # build authentication string with accesstoken and username like documented here # https://docs.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth#authenticate-connection-requests # in the case of client credential usage we need to add the target mailbox like shared mailbox access to the SASL string if ( $targetMailbox) { $SharedMailbox = $targetMailbox } if ( $SharedMailbox ) { $b="user=" + $SharedMailbox + "$([char]0x01)auth=Bearer " + $accessToken + "$([char]0x01)$([char]0x01)" Write-Host "Accessing Sharedmailbox - $SharedMailbox - with Accesstoken of User $userName." -ForegroundColor DarkGreen } else { $b="user=" + $userName + "$([char]0x01)auth=Bearer " + $accessToken + "$([char]0x01)$([char]0x01)" } $Bytes = [System.Text.Encoding]::ASCII.GetBytes($b) $POPIMAPLogin =[Convert]::ToBase64String($Bytes) Write-Verbose "SASL XOAUTH2 login string $POPIMAPLogin" # connecting to Office 365 IMAP Service Write-Host "Connect to Office 365 IMAP Service." -ForegroundColor DarkGreen $ComputerName = 'Outlook.office365.com' ##$Port = '993' $Port = '995' try { $TCPConnection = New-Object System.Net.Sockets.Tcpclient($($ComputerName), $Port) $TCPStream = $TCPConnection.GetStream() try { $SSLStream = New-Object System.Net.Security.SslStream($TCPStream) $SSLStream.ReadTimeout = 5000 $SSLStream.WriteTimeout = 5000 $CheckCertRevocationStatus = $true $SSLStream.AuthenticateAsClient($ComputerName,$null,[System.Security.Authentication.SslProtocols]::Tls12,$CheckCertRevocationStatus) } catch { Write-Host "Ran into an exception while negotating SSL connection. Exiting." -ForegroundColor Red $_.Exception.Message break } } catch { Write-Host "Ran into an exception while opening TCP connection. Exiting." -ForegroundColor Red $_.Exception.Message break } # continue if connection was successfully established $SSLstreamReader = new-object System.IO.StreamReader($sslStream) $SSLstreamWriter = new-object System.IO.StreamWriter($sslStream) $SSLstreamWriter.AutoFlush = $true $SSLstreamReader.ReadLine() Write-Host "Authenticate using XOAuth2." -ForegroundColor DarkGreen # authenticate and check for results ## $command = "A01 AUTHENTICATE XOAUTH2 {0}" -f $POPIMAPLogin $command = "AUTH = XOAUTH2" Write-Verbose "Executing command -- $command" $SSLstreamWriter.WriteLine($command) ## begin $command = $POPIMAPLogin $SSLstreamWriter.WriteLine($command) ## end #respose might take longer sometimes while (!$ResponseStr ) { try { $ResponseStr = $SSLstreamReader.ReadLine() } catch { } } if ( $ResponseStr -like "*OK AUTHENTICATE completed.") { $ResponseStr Write-Host "Getting mailbox folder list as authentication was successfull." -ForegroundColor DarkGreen $command = 'A01 LIST "" *' Write-Verbose "Executing command -- $command" $SSLstreamWriter.WriteLine($command) $done = $false $str = $null while (!$done ) { $str = $SSLstreamReader.ReadLine() if ($str -like "* OK LIST completed.") { $str ; $done = $true } elseif ($str -like "* BAD User is authenticated but not connected.") { $str; "Causing Error: IMAP protcol access to mailbox is disabled or permission not granted for client credential flow. Please enable IMAP protcol access or grant fullaccess to service principal."; $done = $true} else { $str } } Write-Host "Logout and cleanup sessions." -ForegroundColor DarkGreen $command = 'A01 Logout' Write-Verbose "Executing command -- $command" $SSLstreamWriter.WriteLine($command) $SSLstreamReader.ReadLine() } else { Write-host "ERROR during authentication $ResponseStr" -Foregroundcolor Red } # Session cleanup if ($SSLStream) { $SSLStream.Dispose() } if ($TCPStream) { $TCPStream.Dispose() } if ($TCPConnection) { $TCPConnection.Dispose() } } #check for needed msal.ps module if ( !(Get-Module msal.ps -ListAvailable) ) { Write-Host "MSAL.PS module not installed, please check it out here https://www.powershellgallery.com/packages/MSAL.PS/" -ForegroundColor Red; break} # execute function Test-IMAPXOAuth2Connectivity<targetmailbox>" -verbose |
Ergebnis:
2024-12-12/rsc - hier gibt es noch einen Fehler