Exchange OAuth

Seit Exchange 2013 gibt es ein "Organisationszertifikat". Diese Seite beschreibt die Hintergründe und wie Sie damit umgehen:

Microsoft hat mit dem Nov 2023 Security Update für Exchange 2016/2019 die Funktion PowerShell Serialization aktiviert und braucht dazu das Exchange Server Authentication Zertifikat. In dem Zuge gibt es ein neues PowerShell-Skript, welches das Zertifikat prüft und bei der Verlängerung unterstützt
MonitorExchangeAuthCertificate.ps1
https://aka.ms/MonitorExchangeAuthCertificate
https://microsoft.github.io/CSS-Exchange/Admin/MonitorExchangeAuthCertificate/

Authentifizierung per Zertifikat

Mit Exchange 2007 war es das erste Mal möglich, dass Exchange Server eine Organisation direkt mit Exchange Servern einer anderen Organisation Kontakt aufnehmen konnten, um z.B. Frei/Belegt-Zeit abzufragen. Siehe dazu auch Kalenderfederation:E2007. Damals musst der Administrator der abgebenden Organisation ein Dienstkonto samt Kennwort einrichten und diese Zugangsdaten an alle Administratoren der anfragenden Organisationen mitteilen. Eine Änderung des Kennwort bedeutete erneut viel Arbeit für die Administratoren und letztlich hatten mehre Administratoren die gleichen Zugangsdaten, die zugleich auch ein "DomainUser" war. Damit konnte also schon das ein oder andere angestellt werden. Mit Exchange 2010 wurde dann das Microsoft Federation Gateway bereitgestellt und die Exchange Server konnten sich damit ohne Benutzerkonten identifizieren und das Dienstkonto ist entfallen.

Allerdings gibt es nun natürlich weiterhin den Bedarf dass Dienste miteinander arbeiten. Im wesentlichen sind das Exchange, Skype for Business/Lync und SharePoint.

  • Skype For Business kann seine Kontakte in Outlook ablegen
    Siehe dazu Unified Contact Store. Exchange muss dazu natürlich verifizieren, dass der Zugriff "legitimiert" ist.
  • Exchange OWA und Presence
    Umgekehrt kann Exchange in Outlook on the Web auch serverseitig den Präsenzstatus des Anwender verwalten und je nach Version sogar chatten. Dazu möchte Skype for Business natürlich auch den Server identifizieren.
  • SharePoint und Benutzerprofile
    Benutzer können sowohl im Exchange als auch im SharePoint z.B. ihr Profilbild aktualisieren. Denkbar ist natürlich, dass auch andere Dienste auf diese Daten zugreifen.
  • Exchange On-Prem und Office 365 Online
    Auch die beiden Exchange Organisationen beim Hybrid-Mode nutzen OAUTH um sich gegenseitig zu identifizieren, z.B. für RMS, eDiscovery und In-Place Archive

Jeder Datenzugriff muss aber Authentifiziert erfolgen. Der Trick von OAUTH ist, dass der eine Server ein Ticket erstellen kann, von dem der anderen Server die Gültigkeit überprüfen kann. Das funktioniert über "Partner Applikationen". Dazu erstellt Exchange aber auch Skype for Business solch ein Schlüsselpaar und der der jeweils andere Server importiert sich den "Public Key" bei der Einrichtung der Partner Applikation.

Exchange Auth Zertifikat

Bei der Installation des ersten Exchange 2013 Servers generiert das Setup schon ein "Self Signed Zertifikat", welches per Default 5 Jahre gültig ist und auf alle Frontend Server repliziert wird

Exchange 2013 Setup creates a self-signed certificate with the friendly name Microsoft Exchange Server Auth Certificate. The certificate is replicated to all front-end servers in the Exchange 2013 organization.
Quelle: https://technet.microsoft.com/de-de/library/jj150480(v=exchg.160).aspx

Welche Zertifikat Exchange aktuell nutzt, ist mit Get-AuthConfig zu erhalten:

[PS] C:\>Get-AuthConfig

RunspaceId                    : 63f481db-71dd-4989-a094-faaa15ef7100
CurrentCertificateThumbprint  : 03C46B33F33B00B5ABEF123456721E0463412B9C
PreviousCertificateThumbprint :
NextCertificateThumbprint     :
NextCertificateEffectiveDate  :
ServiceName                   : 00000002-0000-0ff1-ce00-000000000000
Realm                         :
DeploymentId                  :
IssuerIdentifier              :
Name                          : Auth Configuration
AdminDisplayName              :
ExchangeVersion               : 0.20 (15.0.0.0)
DistinguishedName             : CN=Auth Configuration,CN=MSXFAQ,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=msxfaq,DC=de
Identity                      : Auth Configuration
Guid                          : 945453c1-64fe-4f00-8b16-c104448502be
ObjectCategory                : msxfaq.de/Configuration/Schema/ms-Exch-Auth-Auth-Config
ObjectClass                   : {top, container, msExchContainer, msExchAuthAuthConfig}
WhenChanged                   : 24.04.2013 14:13:57
WhenCreated                   : 24.04.2013 14:13:56
WhenChangedUTC                : 24.04.2013 12:13:57
WhenCreatedUTC                : 24.04.2013 12:13:56
OrganizationId                :
Id                            : Auth Configuration
OriginatingServer             : DC01.msxfaq.de
IsValid                       : True
ObjectState                   : Unchanged

Hier ist aber nur der "Thumbprint" des aktuellen Zertifikats sichtbar. Aber damit können Sie schon auf die Suche gehen. Mit einem "Get-ExchangeCertificate" sollte das Zertifikat auch erscheinen

[PS] C:\>Get-ExchangeCertificate -Thumbprint 03C46B33F33B00B5ABEF123456721E0463412B9C| fl

AccessRules        :
CertificateDomains : {Federation}
HasPrivateKey      : True
IsSelfSigned       : True
Issuer             : CN=Federation
NotAfter           : 11.01.2017 15:42:32
NotBefore          : 11.01.2012 15:42:32
PublicKeySize      : 2048
RootCAType         : None
SerialNumber       : 73529A9ABCDEF3894C43135E40BA7353
Services           : SMTP
Status             : Valid
Subject            : CN=Federation
Thumbprint         : 03C46B33F33B00B5ABEF123456721E0463412B9C

Das Zertifikat ist per Default 5 Jahre gültig und das "NotBefore"-Datum ist ein guter Indikator, wann in dieser Umgebung das erste mal Exchange 2013 oder Exchange 2016 installiert wurde. Das gleiche Zertifikat wird übrigens auch für die Verbindung zum Microsoft Federation Gateway genutzt.

AuthServer in Office 365

Ähnlich wie bei ADFS-Servern "vertraut" Exchange per Default nicht jedem dahergelaufenen Server. Über die "AuthServer" Einstellungen wird Exchange mitgeteilt, von welchen Servern Exchange ausgestellte Tokens akzeptiert.

An authorization server is a server or service that issues tokens trusted by Microsoft Exchange for access by partner applications.
Quelle: https://technet.microsoft.com/en-us/library/jj218613(v=exchg.160).aspx

Ein Get-AuthServer liefert in Office 365 am 23.11.2016 folgende Liste:

# Office 365 AuthServer (Stand 23.11.2016
PS C:\> Get-AuthServer | ft name,tokenissuingendpoint -au

Name                TokenIssuingEndpoint
----                --------------------
MicrosoftSts        https://accounts.accesscontrol.windows.net/tokens/OAuth/2
EvoSts              https://login.windows.net/common/oauth2/token
Facebook            https://graph.facebook.com/oauth/access_token
LinkedIn            https://api.linkedin.com/uas/oauth/accessToken
SandboxFacebook     http://fakedEndPoint
SandboxLinkedIn     http://fakedEndPoint
SandboxGoogle       http://fakedEndPoint
SandboxTwitter      http://fakedEndPoint
SandboxYahoo        http://fakedEndPoint
Dropbox             https://api.linkedin.com/uas/oauth/accessToken
SandboxSinaWeibo    http://fakedEndPoint
OutlookMobileGoogle http://fakedEndPoint
Box                 https://api.linkedin.com/uas/oauth/accessToken
OwaUserVoice        https://outlook.Uservoice.com/oauth/request_token
GoogleId            https://www.googleapis.com/oauth2/v4/token
SubstrateSts        https://localhost:444/SubstrateTokenIssuer/tokens/1
ebClientGoogle      http://fakedEndPoint

On-Premises sind die Einträge deutlich kürzer.

Renewal und Reparatur

Microsoft hat mit dem Nov 2023 Security Update für Exchange 2016/2019 die Funktion PowerShell Serialization (PS Serialization) aktiviert und braucht dazu das Exchange Server Authentication Zertifikat. In dem Zuge gibt es ein neues PowerShell-Skript, welches das Zertifikat prüft und bei der Verlängerung unterstützt
MonitorExchangeAuthCertificate.ps1
https://aka.ms/MonitorExchangeAuthCertificate
https://microsoft.github.io/CSS-Exchange/Admin/MonitorExchangeAuthCertificate/

Exchange legt bei der Installation ein 5 Jahre lang gültiges Zertifikat ab. Es gibt aber keinen Prozess dieses Zertifikat automatisch zu verlängern. Das können Sie sich also schon mal in den Kalender schreiben, um die folgenden Befehle dann auszuführen:

New-ExchangeCertificate `
   -KeySize 2048 `
   -PrivateKeyExportable $true `
   -SubjectName "cn=Microsoft Exchange Server Auth Certificate" `
   -DomainName "*.<primaryMaildomain>" `
   -FriendlyName "Microsoft Exchange Server Auth Certificate" `
   -Services SMTP

An einigen Quellen kommt als Name auch "Microsoft Exchange ACS Certificate" vor

Die Angabe eines "Service" ist erforderlich, auch wenn das Zertifikat dazu später nicht eingesetzt wird. Das Commandlet wird nach der Generierung nachfragen, ob das eventuell bestehende Zertifikat überschrieben werden soll. Da antworten Sie natürlich mit "NEIN". Das neue Zertifikat müssen Sie natürlich noch aktiv schalten. Das geht mit:

Set-AuthConfig `
   -NewCertificateThumbprint your_certificate’s_thumbprint_goes_here `
   -NewCertificateEffectiveDate (get-date)

Das Zertifikat muss natürlich noch "veröffentlicht" werden. Auch das geht mit der Powershell

Set-AuthConfig `
   -PublishCertificate

Wenn das alles funktioniert hat, dann sollten Sie das vorherige Zertifikat auch wieder entfernen.

Set-AuthConfig `
   -ClearPreviousCertificate

Am Ende ist ein IISRESET erforderlich, damit die Dienste das neue Zertifikat nutzen.

Wenn Sie Exchange Hybrid nutzen, dann müssen Sie hier natürlich auch noch das Zertifikat zu Exchange Online übertragen.

Exchange Hybrid

Das OAUTH-Zertifikat wird von Exchange Online ebenfalls genutzt, um Free/Busy-Zeiten zu erhalten. Wenn Sie das lokale Zertifikat ändern, dann müssen Sie dies auch in die Cloud hochladen. Am einfachsten geht dies über den Hybrid Configuration Wizard. Über die AzureAD-Powershell können Sie sehen, welches Zertifikat die Cloud kennt.

Get-AzureADServicePrincipal `
   -SearchString "Office 365 Exchange Online" `
| Get-AzureADServicePrincipalKeyCredential

Das Vorgehen hat Microsoft gut beschrieben:

Test mit Test-OAuthConnectivity

Um die Verbindung von Exchange Online zum lokalen Exchange Server zu testen, bietet die Exchange Online PowerShell das Commandlet "Test-OAuthConnectivity".

Der Vorteil dabei ist, dass die Anfrage wirklich aus der Cloud mit den gleichen IP-Adressen ankommt wie auch später von Exchange Online. Sie können also nicht nur die generelle Erreichbarkeit prüfen, sondern acuh in ihrer Firewall die Zugriffe sehen. Ein Aufruf könnte daher sein:

Test-OAuthConnectivity `
   -Service EWS `
   -TargetUri https://hybrid.msxfaq.de `
   -Verbose `
   -Mailbox user1@msxfaq.de

Die TargetURI muss nur der Host sein und alles nach dem Hostname wird eh abgeschnitten. Die Mailbox gibt ein Exchange Online Postfach vor, in dessen Auftrag dann die Anfrage gestellt wird.

Tipp: Modifizieren sie vorher das IISLogging, damit auch der Hostheader und der Authentication-Header protokolliert.

Exchange Online stellt natürlich die die Frage per HTTPS an ihren lokalen Exchange Server. Aber auch dann können Sie im IISLog durchaus die Zugriffe sehen. Hier eine Zeile decodiert.

s-ip                  = 192.168.100.33 
cs-method             = POST 
cs-uri-stem           = /ews/Exchange.asmx 
cs-uri-query          = &CorrelationID=<empty>;&cafeReqId=903de4b2-4133-4d0e-9ae1-78-5-21-11949449-30417519-71842111-1009
c-ip                  = 92.168.100.5 
cs-host               = owa.msxfaq.de
cs(User-Agent)        = AMProbe/OAUTH/Exchange 
cs(Referer)           = - 
sc-status             = 200 
sc-substatus          = 0 
sc-win32-status       = 0 
sc-bytes              = 2340 
cs-bytes              = 3703 
time-taken            = 46
Request-Authorization = Bearer+eyJuYW........ 
X-Forwarded-For       = 40.99.157.189

Eine Suche nach dem UserAgent "AMProbe/OAUTH/Exchange" sollte die entsprechenden Zeilen schnell liefern und dann ist der "sc-status" als auch das Feld "Request-Authorization" interessant. Das sollte mit "bearer" starten und die Buchstabenwüste können Sie einfach z.B. mit https://jwt.io oder https://jwt.ms/ decodieren. Allerdings ist das erste ein einfaches Token.

Sie sehen hier aber schon den Benutzer, für den das Token ausgestellt wurde. Wer aber genauer hinschaut, findet ein "actortoken", welches sich ebenfalls decodieren lässt:

Hier sehen wir dann wieder die Exchange Online Apps. Wer noch etwas weiter schauen will, kann nun noch mit FREB (Siehe IIS - Webserver Troubleshooting) auf dem Exchange Server die Verarbeitung genauer analysieren. Sie sollten dann zwei Requests sehen:

Der erste Request erfolgt anonym, wobei Exchange Online schon mitliefert, dass er "Bearer" versteht:

Damit weiß Exchange Online nun, welche App der Server akzeptiert und Exchange Online kann sich ein passendes Ticket für den nächsten Request besorgen.

Wenn die Funktion im Grunde gegeben ist, dann können sie auch absichtlich Fehler einbauen und die Fehlermeldungen analysieren.

Fehler Meldung

TargetMailbox gibt es nicht in Exchange Online

Exchange Online startet gar nicht erst eine Verbindung zum Zielsystem sondern bricht direkt auf der Powershell ab:

Test-OAuthConnectivity: Ex6F9304|Microsoft.Exchange.Configuration.Tasks.ManagementObjectNotFoundException|
   Der Vorgang konnte nicht ausgeführt werden, weil das Objekt 'noexouser@msxfaq.de' nicht auf 
'FR2P281A07DC001.DEUP281A007.PROD.OUTLOOK.COM' gefunden wurde.

TargetUri nicht gültig

Exchange Online versucht per DNS den Namen aufzulösen und schafft dies nicht. Die Powershell liefert keinen Fehler aber die Rückgabe von Test-OAuthConnectivity enthält den Fehler:

System.Net.WebException: The remote name could not be resolved: 'hybrid2.msxfaq.de'

TargetUri ist kein Exchange oder EWS nicht erreichbar

Exchange Online versucht per DNS den Namen aufzulösen und schafft dies nicht. Die Powershell liefert keinen Fehler aber die Rückgabe von Test-OAuthConnectivity enthält den Fehler.

System.Net.WebException: The remote server returned an error: (404) Not Found.

On-Premises System beendet die Verbindung z.B. wegen TLS-Inkompatibilität

Exchange Online findet den Server per DNS aber entweder kommt ein TCP-Reset oder TLS-Abbruch:

System.Net.WebException: The underlying connection was closed:
  An unexpected error occurred on a receive.
---> System.IO.IOException: Unable to read data from the transport connection:
An existing connection was forcibly closed by the remote host

Tenant1 versucht Daten von fremder On-Premises-Umgebung abzurufen, wozu er nicht berechtigt ist.

Exchange Online versucht es aber die OnPrem-Umgebung verwirft die Anfrage mit einem Diagnosecode 2000009.

System.Net.WebException: The remote server returned an error: (401) Unauthorized. 
  at System.Net.HttpWebRequest.GetResponse() 
  at Microsoft.Exchange.Monitoring.TestOAuthConnectivityHelper.SendExchangeOAuthRequest
   diagnostics: 2000009;reason="The issuer of the token is unknown. 
               Issuer was '00000 001-0000-0000-c000-000000000000@<TeantnGUID>'.";error_category="invalid_issuer"

Kein Hostheader

Die HTTP-Anfrage wird mit einem 401 und einem Diagnosecode 2000003 beendet.

System.Net.WebException: The remote server returned an error: (401) Unauthorized.
diagnostics: 2000003;reason="The hostname component of the audience claim value
              'https://owa.msxfaq.de' is invalid";error_category="invalid_resource"

Exchange mag den Claim nicht, weil der Hostheader nicht zum AUD-Hostname übereinstimmt.

EXO sendet einen Namen mit, der nicht im OAUTH Zertifikat von Exchange enthalten ist.

System.Net.WebException: The remote server returned an error: (401) Unauthorized.
                 at System.Net.HttpWebRequest.GetResponse()
                 at Microsoft.Exchange.Monitoring.TestOAuthConnectivityHelper.SendExchangeOAuthRequest(ADUser user,
              String orgDomain, Uri targetUri, String& diagnosticMessage, Boolean appOnly, Boolean useCachedToken,
              Boolean reloadConfig), 
   diagnostics: 2000003;reason="The hostname component of the audience claim value is invalid. 
        Expected 'owa.msxfaq.de'. Actual 'hybrid.msxfaq.de'.";error_category="invalid_resource"

Häufiger Fehler ist hier SSL-Offloading, da HTTP eben nicht HTTPS ist.

Ich habe zwar keinen Zugriff auf den Source Code aber meine Ergebnisse interpretiere ich wie folgt:

  • HostHeader muss mit Name in "AUD" übereinstimmen
    Das bedeutet aber auch, dass jeder Request auch immer einen Hostheader mitsenden muss, da ansonsten Exchange dies mit einem "“diagnostics: 2000003; The hostname component of the audience claim value is invalid" quittiert
  • AUD-Name nicht im MSOLServicePrinzipalname erforderlich
    Zumindest hat bei mir ein "Test-OAuthConnectivity" auch problemlos ein OAUTH-Token für einen nicht im AzureAD definierten Namen anfordern und zusenden können. Dennoch ist es besser, einen Namen anzulegen. Vielleicht gibt es andere Dienste, die hier anders reagieren.
  • ExternalURL auf OnPrem-Server irrelevant
    Meine Vermutung hat sich nicht bestätigt, dass Exchange 2013/2016 lokal einen Wert aus ExternalURL oder einer anderer Quelle heranzieht. Es zählt allein der HostHeader im Request

ich tippe darauf, dass Exchange den "Host Header" im HTTP-Request mit dem AUD-Feld im OAUTH-

 

Exchange Partner Applikation

Die Funktion und Einrichtung einer "Partner App" habe ich auf Exchange Partner Application beschrieben.

Weitere Links