EWS und Impersonation

Impersonation ist der Weg, einer Applikation des Recht einzuräumen so zu arbeiten, als wäre sie als Benutzer angemeldet. Diese Anforderung gibt es für ERP/CRM-Systeme, Archiv-Produkte und viele anderen Dinge, die stellvertretend für den Anwender etwas tun sollen.

Für erste Tests können Sie mit Test-EWS starten

Warum Impersonation?

In der Regel hat eine Applikation natürlich nicht die Zugangsdaten eines Benutzers. Aber selbst wenn Sie einem Dienstkonto alle Rechte einräumen, die auch der Anwender hat, ist es trotzdem nicht das gleiche mit dem Dienstkonto auf Informationen zuzugreifen. Ein einfaches Beispiel: Wenn Sie ein Objekt neu anlegen, bekommt es nicht nur die Berechtigungen des darüber liegenden Objekts. Es bekommt aber auch einen "Besitzer". Auch wenn ein Dienstkonto das Recht hat in einem Ordner oder Postfach ein Element anzulegen, dann ist nicht der Benutzer selbst der "Besitzer" sondern eben das Dienstkonto wird als "Creator" eingetragen. Zumindest bei Zugriffen über ein "Full Access"-Recht.

Besser ist es daher, wenn ein Prozess sich "als Benutzer" ausgeben kann. Genau das ist mit dem "Impersonation-Recht" per EWS möglich.

Eine ähnliche Option gibt es auch für den Zugriff von Computern und Dienstkonten in Verbindungen mit der eigentlichen Authentifizierung per Kerberos. Auch hier kann eine Impersonation konfiguriert werden. Dabei "sieht" der Dienst aber nicht mehr selbst, dass der Zugriff über ein Dienstkonto erfolgt, sondern der Dienst bekommt wirklich ein Kerberos-Ticket mit den Benutzerdaten vom KDC. Das Verfahren hierzu heißt dann "Kerberos Contraint Delegation"

Achtung:
Die Einrichtung von Impersonation bei Exchange 2007 unterscheidet sich grundlegend von Exchange 2010 und neuer

Exchange 2010/2013: EWS Impersonation

Mit Exchange 2010 wurde die Steuerung der Berechtigung über "RBAC" geregelt, so dass eine direkte Vergabe von Rechten an die CAS-Server oder Postfächer entfällt. Dafür bekommt ein Konto nun über eine Rollenzuweisung das Recht "Impersonation", welche optional noch mit einem "Scope" auf bestimmte Zielebeschränkt wird. Es müssen also drei Fakten zusammen kommen

  1. Ein Objekt, welches die Rechte bekommt
    Das kann ein Benutzer direkt oder eine Gruppe sein, in der berechtige Benutzer Mitglied sind
  2. Ein Application Recht
    welches zugelassen wird
  3. Ein Scope, d.h. die Teilmenge der Ziele
    Ohne Scope wirkt das Recht auf alle möglichen Objekte. Ein Scope muss vorher über einen OOPATH-Filter definiert werden

Entsprechend gibt es PowerShell-Commandlets. Einige Funktionen sind auch per Exchange Control Panel möglich.

[PS] C:\>get-command Get-Management*

CommandType     Name
-----------     ----
Function        Get-ManagementRole
Function        Get-ManagementRoleAssignment
Function        Get-ManagementRoleEntry
Function        Get-ManagementScope

Auf einem Exchange 2016 Server gibt es dazu schon eine entsprechend angelegte Rollengruppe "User Impersonate" und eine Rolle "ApplicationImpersonation".

Der Gruppe "User Impersonate" ist also das Recht zugewiesen, alle Objekte im Schreibbereich (Scope) "Standard" (Also alle) Impersonation zu nutzen.

Das Feld, in dem hier "Standard" steht, ist eine DropDown -Liste. Wenn Sie später eigene Scopes definieren, können Sie dieser hier auswählen.

In diesem Beispiel ist das Konto "CRMSync" sogar Mitglied der Gruppe, um vermutlich bei den Benutzern entsprechende Aufgaben, Termin und Kontakte zu pflegen und Mails zu verarbeiten. Die Role Groups sind einfache Windows Sicherheitsgruppen im Container "MIcrosoft Exchange Security Groups" und so auch über die MMX für Active Directory Benutzer und Computer zu sehen und zu bearbeiten.

Exchange Management Rolle für Impersonation

Die Rolle selbst ist wie folgt definiert:

Per PowerShell gibt es noch ein paar Details:

[PS] C:\Windows\system32>Get-ManagementRole *imper* |fl

RoleEntries                 : {Impersonate-ExchangeUser}
RoleType                    : ApplicationImpersonation
ImplicitRecipientReadScope  : Organization
ImplicitRecipientWriteScope : Organization
ImplicitConfigReadScope     : None
ImplicitConfigWriteScope    : None
IsRootRole                  : True
IsEndUserRole               : False
MailboxPlanIndex            :
Description                 : This role enables applications to impersonate Users in an organization in order to
                              perform tasks on behalf of the User.
IsDeprecated                : False
ExchangeVersion             : 0.12 (14.0.451.0)
Name                        : ApplicationImpersonation
DistinguishedName           : CN=ApplicationImpersonation,CN=Roles,CN=RBAC,CN=MSXFAQ,CN=Microsoft
                              Exchange,CN=Services,CN=Configuration,DC=msxfaq,DC=de
Identity                    : ApplicationImpersonation
ObjectCategory              : msxfaq.de/Configuration/Schema/ms-Exch-Role
ObjectClass                 : {top, msExchRole}
WhenChanged                 : 26.10.2009 14:46:09
WhenCreated                 : 26.10.2009 14:46:06
OrganizationId              :
Id                          : ApplicationImpersonation

Sie sehen gut, dass diese Rolle mit der Installation von Exchange 2010 gekommen und seit dem nicht mehr geändert wurde.

Scope festlegen

Wenn Sie eine Management Rolle einfach direkt an eine Person oder eine Gruppen ohne weitere Einschränkungen zuweisen wollen, dann können Sie diesen Abschnitt überspringen. Allerdings ist es eher ungewöhnlich gerade beim Bereich "Impersonation" einem Konto Zugriff auf alle Postfächer einer Exchange Umgebung zu geben. Der Trick ist die Berechtigungen über den Scope zu beschränken. Über ECP können Sie hier erst einmal nur "Standard" oder eine OU angeben:

Für alle anderen Teilmengen ist zuerst ein Scope anzulegen. Dies geht allerdings nur per PowerShell:

Gültige Filter sind z.B.: Server, ADSite, Datenbank, OU, RecipientType, Titel, Gruppenmitgliedschaft.

You can use almost any property on a recipient object when you create a recipient filter. For a list of filterable recipient properties, see Filterable properties for the -RecipientFilter parameter. Although this topic discusses the properties that can be used with the RecipientFilter parameter on other cmdlets, most of these properties also work with the RecipientRestrictionFilter parameter on the New-ManagementScope cmdlet.
Quelle Understanding management role scope filters  https://technet.microsoft.com/en-us/library/dd298043(v=exchg.150).aspx

In den seltensten Fällen wird die Zielgruppe für eine Impersonation sich auf eine AD-Site, Server oder Datenbank beschränken lassen. Eine OU ist in vielen Fällen möglich aber diverse Felder wie "Title" oder die ExtensionAttribute sind "Vertipper"-gefährdet. Insofern gefällt mir die Steuerung über eine Gruppe sehr gut. Allerdings sind dabei einige Besonderheiten zu beachten:

Der RecipientFilter wird mit dem Schlüsselwort "MemberOfGroup" gestartet und verweist auf den DN der Gruppe. Da es sich um ein Backlink-Attribut handelt, ist die Performance zu bedenken und wenn sich der DN ändert, greift der Filter nicht mehr.

Ich lege mir also erst eine Gruppe an, in der später alle Postfächer aufgenommen werden, auf die ein Dienstkonto die Impersonate-Berechtigungen bekommt. Hier als Beispiel, wie ich dem Dienstkonto "svc-webcon" das Recht geben, alle Postfächer per Impersonate zu öffnen, die in der Gruppe "webcon-ewsimpersonateUser" Mitglied sind.

# Verteilergruppe fuer Scope-Postfacher anlegen
New-Distributiongroup `
   -name "webcon-ewsimpersonateUser" `
   -Displayname "webcon-ewsimpersonateUser" `
   -Type "Distribution" `
   -Organizationalunit "OU=delegategroup,DC=msxfaq,DC=de"

# Management Scope anlegen
New-ManagementScope `
   -Name:"WebConImpersonateScope" `
   -RecipientRestrictionFilter {MemberOfGroup -eq "CN=webcon-ewsimpersonateUser,OU=delegategroup,DC=msxfaq,DC=de"}

#Role zuweisen
New-ManagementRoleAssignment `
   -Name:Webcon-impersonation `
   -Role:ApplicationImpersonation `
   -CustomRecipientWriteScope WebConImpersonateScope `
   -User: svc-webcon

Kleine Anekdote am Rande: Ich habe einmal versucht, einen zweiten Scope mit dem gleichen Filter anzulegen. Das hat die Exchange PowerShell blockiert
The WebConImpersonateScope management scope has the same RecipientRoot, RecipientFilter, ServerFilter, ScopeRestrictionType or Exclusive property values that you specified. Use the existing management scope instead of creating a new one.

Denken Sie sich bitte einen "sprechenden Namen" aus, denn in im ECP (Exchange Control Panel) werden diese Scopes sichtbar.

Impersonation zuweisen

Damit ein Account oder eine Gruppe das Recht "Impersonate" hat, wird eine Management-Rolle zugewiesen mit:

New-ManagementRoleAssignment `
    -Name:impersonationAssignmentName `
    -Role:ApplicationImpersonation `
    -User:serviceAccount

Oder bei Zuweisung an eine Gruppe über:

New-ManagementRoleAssignment `
    -Name:impersonationAssignmentName `
    -Role:ApplicationImpersonation `
    -Securitygroup:Gruppenname

Der große Vorteil von "Impersonation" gegenüber "Delegation" ist, dass bei Impersonate die Throttling Policies des Postfachs für jedes Postfach getrennt angewendet werden und nicht das Dienstkonto global beschränkt wird.

Die neuen Berechtigungen werden nicht sofort aktiv. Warten Sie die AD-Replikation ab. Gruppenmitgliedschaften wirken erst, wenn das Konto sich neu anmeldet. Auch der Exchange Server hat einen "Cache" um nicht bei jedem Zugriff alle Rechte nur zu bewerten

Die Erlaubnis, dass ein Konto ein "Impersonation"-Aufruf an einen CAS-Server absetzen darf, bedeutet noch nicht, dass er alle Postfächer auch erreichen kann. Das Konto muss weiterhin die Berechtigungen auf Server, Datenbanken oder einzelne Postfächer bekommen.

Änderungen werden nicht sofort aktiv, da sowohl die AD-Replikation als auch der Exchange Cache zu Verzögerungen führen, insbesondere wenn Sie es vor Kurzem schon mal "probiert" haben und die Information im Cache noch jung ist. Manchmal reicht es den IIS Application Pool "MSExchangeServicesAppPool" durchzustarten, um den Cache zu leeren.

Impersonation Vererbung

Sie können sowohl das recht für Impersonation über eine Gruppe delegieren als auch eine gruppe als Scope verwenden. Da stellt sich mir die Frage, ob das auch rekursiv wirkt.

  • Delegierung von Impersonation - JA
    Ich habe daher einer Gruppe das Impersonation-Recht gegeben und das Dienstkonto nicht direkt addiert sondern über eine andere Gruppe in die Gruppe aufgenommen. Das Dienstkonto hatte dann dennoch das Impersonation-Recht bekommen. Also auch hier wird eine Vererbung richtig umgesetzt.
  • Scope mit rekursiven Gruppen - NEIN
    Dann habe ich einen Scope genutzt, der mit "MemberOfGroup" eine Impersonation auf alle Mitglieder der Gruppen steuert. In diese Gruppe habe ich dann wieder eine Gruppe addiert, in der ein Postfach lag. Hier hat dann aber keine Rekursion gegriffen. Anscheinend prüft Exchange beim OPATH-Filter wirklich nur die direkte Gruppenmitgliedschaft.

Anzeigen der Impersonation-Einstellungen

Bei Exchange On-Prem können Sie über einen PowerShell-Einzeiler schnell ermitteln, welche Zuweisungen der Rolle "ApplicationImpersonation" gerade konfiguriert sind.

Get-ManagementRoleAssignment `
   -Role ApplicationImpersonation `
| ft name,RoleAssigneeName,RoleAssigneeType,CustomRecipientWriteScope -AutoSize

Name                                                         RoleAssigneeName         RoleAssigneeType   CustomRecipientWriteScope
----                                                         ----------------         ----------------   ------------------
ApplicationImpersonation-Hygiene Manageme                    Hygiene Management       RoleGroup
ApplicationImpersonation-Organization Management-Delegating  Organization Management  RoleGroup
ApplicationImpersonation-User Impersonate                    User Impersonate         RoleGroup
Webcon-impersonation                                         svc-webcon               User                WebConImpersonation

Schöner ist die Ausgabe natürlich als GridView:

Get-ManagementRoleAssignment `
   -Role ApplicationImpersonation `
| select name,RoleAssigneeName,RoleAssigneeType,CustomRecipientWriteScope `
| Out-GridView

Es macht durchaus immer mal wieder Sinn, sich diese Rechte anzuschauen. Allzu leicht schleicht sich hier ein unerwünschter Eintrag ein.

Impersonation in Office 365

Auch in Office 365 gibt es natürlich die Funktion "Impersonate". Analog zu Exchange On-Prem können Sie auch in Office 365 über ECP die Managementrollen verwalten. Die Funktion ist besonders für 3rd Party-Tools wichtig, die z.B. Mails in die Cloud migrieren. Aber auch andere Programme nutzen EWS um Daten für Anwender zu verändern. Per Exchange PowerShell sehen Sie sehr schnell, was die Standardeinstellungen sind:

# PowerShell zu Exchange ONline herstellen.
$Session = New-PSSession `
    -ConfigurationName Microsoft.Exchange `
    -ConnectionUri https://ps.outlook.com/PowerShell/ `
    -Credential (get-credential) `
    -Authentication Basic `
    -AllowRedirection 

Import-PSSession $session


# Anzeigen der Standard Assignments
Get-ManagementRoleAssignment *imper* |fl

DataObject                   : ApplicationImpersonation-Organization
                               Management-Delegating 
User                         : Organization Management
AssignmentMethod             : Direct
Identity                     : ApplicationImpersonation-Organization
                               Management-Delegating
EffectiveUserName            : Alle Gruppenmitglieder
AssignmentChain              :
RoleAssigneeType             : RoleGroup
RoleAssignee                 : Organization Management
Role                         : ApplicationImpersonation
RoleAssignmentDelegationType : DelegatingOrgWide
CustomRecipientWriteScope    :
CustomConfigWriteScope       :
RecipientReadScope           : Organization
ConfigReadScope              : None
RecipientWriteScope          : Organization
ConfigWriteScope             : None
Enabled                      : True
RoleAssigneeName             : Organization Management
IsValid                      : True
ExchangeVersion              : 0.11 (14.0.550.0)
Name                         : ApplicationImpersonation-Organization
                               Management-Delegating
ObjectCategory               : EURPR06A003.prod.outlook.com/Configuration/Schem
                               a/ms-Exch-Role-Assignment
ObjectClass                  : {top, msExchRoleAssignment}
                             : ApplicationImpersonation-Organization Management-Delegating
OriginatingServer            : AM3PR06A003DC01.EURPR06A003.prod.outlook.com
ObjectState                  : Unchanged



DataObject                   : ApplicationImpersonation-RIM--MailboxAdmins6cfb9a96782249a2a0123456789000 
User                         : RIM-MailboxAdmins6cfb9a96782249a2a0123456789000
AssignmentMethod             : Direct
EffectiveUserName            : Alle Gruppenmitglieder
AssignmentChain              :
RoleAssigneeType             : RoleGroup
RoleAssignee                 : RIM-MailboxAdmins6cfb9a96782249a2a0123456789000
                               0
Role                         : ApplicationImpersonation
RoleAssignmentDelegationType : Regular
CustomRecipientWriteScope    :
CustomConfigWriteScope       :
RecipientReadScope           : Organization
ConfigReadScope              : None
RecipientWriteScope          : Organization
ConfigWriteScope             : None
Enabled                      : True
RoleAssigneeName             : RIM-MailboxAdmins6cfb9a96782249a2a0123456789000
                               0
IsValid                      : True
ExchangeVersion              : 0.11 (14.0.550.0)
Name                         : ApplicationImpersonation-RIM-MailboxAdmins6cfb9a
                               96782249a2a0a984
ObjectCategory               : EURPR06A003.prod.outlook.com/Configuration/Schem
                               a/ms-Exch-Role-Assignment
ObjectClass                  : {top, msExchRoleAssignment}
WhenChanged                  : 11.08.2016 06:01:30
WhenCreated                  : 14.05.2015 21:50:48
WhenChangedUTC               : 11.08.2016 04:01:30
WhenCreatedUTC               : 14.05.2015 19:50:48
OrganizationId               : EURPR06A003.prod.outlook.com/Microsoft Exchange
                               Hosted Organizations/msxfaq.onmicrosoft.com - EU
                               RPR06A003.prod.outlook.com/ConfigurationUnits/ms
                               xfaq.onmicrosoft.com/Configuration
Id                           : ApplicationImpersonation-RIM-MailboxAdmins6cfb9a96782249a2a0123456789000
OriginatingServer            : AM3PR06A003DC01.EURPR06A003.prod.outlook.com
ObjectState                  : Unchanged

In meinem Tenant gibt es also zwei Impersonation-Rollen.

Wenn Sie eine etwas größere Office 365 Umgebung betreiben, dann legen SIe in der Regel weder Benutzer noch Gruppen manuell an. Das ist also die Aufgabe des AADConnect/ADSync, die Benutzer und Gruppen in Office 365 synchron zu halten. Das ist insbesondere im Hybrid-Mode ratsam, da dann der Scope beibehalten wird, wenn die Postfächer verschoben werden. Ich habe daher etwas gewartet, bis AADConnect das Dienstkonto und die Gruppe auch in der Cloud angelegt und die Mitglieder gepflegt hat. Ein "Get-Distributiongroupmember" erlaubt die Kontrolle.

Ich muss dann keine eigene Berechtigungsgruppe mehr anlegen und definiere einfach einen passenden Scope:

# CloudDN der Gruppe ermitteln
$clouddn = (Get-DistributionGroup webcon-ewsimpersonateUser).DistinguishedName

# Management Scope anlegen
New-ManagementScope `
   -Name:"WebConImpersonateScope" `
   -RecipientRestrictionFilter ("{MemberOfGroup -eq '"+$clouddn+"'}")

#Role zuweisen
New-ManagementRoleAssignment `
   -Name:Webcon-impersonation `
   -Role:ApplicationImpersonation `
   -CustomRecipientWriteScope WebConImpersonateScope `
   -User:svc-webcon@msxfaq.de

Beachten Sie, dass Sie in Office 365 den DN des AzureAD-Objects bei MemberOfGroup verwenden müssen.

Impersonation auf sich selbst

Sie können per EWS in der Regel ihr eigenes Postfach direkt öffnen, zumindest wenn der Administrator den EWS-Zugang für sie nicht gesperrt hat. Das bedeutet aber nicht, dass Sie "Impersonate" auf sich selbst machen können. Dazu müssen Sie die Rechte habe. In diese Falle laufen oft 3rd Party Programme, die per Impersonation auf viele andere Postfächer zugreifen aber im Scope vergessen wurde, das Postfach des Dienstkontos zu addieren. Wenn der Entwickler dann generell immer mit Impersonation arbeitet, dann bekommt er den lapidaren Fehler, dass er keine Rechte hat.

Fehler bei Impersonation

Ich habe sicher noch nicht alle Fehlermeldungen bei Impersonation gesehen. Aber einige Ausnahmen in PowerShell und deren Ursache und Lösung habe ich hier gesammelt:

Ausnahme Beschreibung und Lösung

The Autodiscover service couldn't be located

Die EWS-Services suchen den Weg zum Postfach per Autodiscover. Prüfen Sie die angegeben Mailadresse des Benutzers, der sich anmelden will und die Gültigkeit der Anmeldedaten.

The account does not have permission to impersonate the requested User

Hier fehlt es an den Berechtigungen überhaupt Impersonation zu machen. Prüfen Sie das RoleAssignment und den Scope. Wurde das Recht gerade erst eingerichtet, kann es einige Stunden dauern, bis es aktiv wird. Oder sie starten den IIS Application Pool "MSExchangeServicesAppPool" durch.

The primary SMTP address must be specified when referencing a mailbox.

Beim Zugriff auf das Zielpostfach muss immer die primäre Adresse angegeben werden. Es kann nicht eine sekundäre Adresse verwendet werden.

The request failed. Der Remoteserver hat einen Fehler zurückgegeben: (503) Server nicht verfügbar.

Anscheinend ist der WebServer erreichbar aber die EWS-Application nicht. Eine Fehlersuche auf dem IIS bzw. Exchange ist erforderlich.

Weitere Fehler werden ich nach und nach addieren.

Exchange 2007 "Impersonation" über "ms-Exch-EPI-May-Impersonate"

Oft reicht es nicht per EWS einfach sein eigenes Postfach zu öffnen. So wird es immer Dienstkonten geben, die in Postfächer anderer Benutzer zugreifen müssen. Dazu gibt es wie bei MAPI ebenfalls drei Optionen:

  • Der Dienst hat Username/Kennwort und meldet sich damit explizit an
    Das kann z.B. ein Webportal machen, an dem sich der Benutzer selbst z.B.: über ein Formular angemeldet hat, so dass das Programm selbst die Zugangsdaten in Klartext hat. Alternativ kann er diese Rechte über Kerberos Constraint Delegation erhalten.
  • Der Dienst hat die erforderlichen Berechtigungen auf den Postfächern bzw. Datenbanken
    Dies eignet sich z.B. wenn nur auf bestimmte Postfächer zugegriffen werden soll (Siehe Mailboxrechte).
  • EWS Impersonation
    Sie können aber einem Dienstkonto auch explizit auf dem CAS-Server das Recht "ms-Exch-EPI-may-Impersonate" geben. Diese Funktion nutzt z.B. auch die TransporterSuite.

Der letzte Fall ist das Thema dieses Abschnitts. Da der erste CAS-Server schon die Anmeldung übernimmt und die Server untereinander "vertrauenswürdig" sind, ist damit ein Durchgriff auf alle Postfächer auch in anderen Standorten (CAS zu CAS Proxy) möglich. Damit kann ich einem Konto das Recht geben, quasi als der angegebene Benutzer zu arbeiten, ohne sich explizit mit dessen Anmeldedaten zu authentifizieren. Dazu unterscheidet Exchange zwei fast gleichlautende Berechtigungen:

  • ms-Exch-EPI-Impersonation
    Dieses Recht kann man auf dem CAS-Server vergeben, damit ein Benutzer die Funktion "Impersonation" überhaupt verwenden darf
  • ms-exch-epi-may-impersonate
    Dieses Recht regelt auf der Postfachdatenbank oder dem einzelnen Postfach, ob die Daten darin über einen Impersonate-Aufruf angesprochen werden dürfen.

Diese beiden Berechtigungen sind also unabhängig von den üblichen "Vollzugriffs-Rechten" auf Postfächer zu sehen, wie diese auf Mailboxrechte beschrieben werden. Impersonation greift nur beim Zugriff über Webservices während die normalen Postfachrechte für den Zugriff über OWA, MAPI, CDO etc. erforderlich sind.

The calling account cannot be a member of any administrator group.
This permission is explicitly denied to those groups

Quelle: Configuring Exchange Impersonation (Exchange Web Services) http://msdn.microsoft.com/en-us/library/exchange/bb204095(v=exchg.80).aspx

Die Einrichtung dieser Berechtigungen ist nur über die PowerShell möglich. Hier am Beispiel eines CAS-Server.

Add-ADPermission `
  -Identity CAS1 `
  -User SVCUser`
  -extendedRights ms-Exch-EPI-Impersonation

Oder hier über eine Schleife, um alle CAS-Server auf einmal zu konfigurieren:

Get-ExchangeServer `
   | where {$_.IsClientAccessServer -eq $TRUE} `
   | ForEach-Object {Add-ADPermission `
                       -Identity $_.distinguishedname  `
                       -User (Get-User -Identity SVCUser `| select-object).identity  `
                       -extendedRights ms-Exch-EPI-Impersonation `
                    }

Die Berechtigungen auf die Postfachdatenbank ist über folgenden Befehl möglich:

Add-ADPermission `
  -Identity SG1/MBDATABASE1 `
  -User SVCUser`
  --ExtendedRights ms-Exch-EPI-May-Impersonate

Oder auch hier wieder für den Zugriff auf alle Postfächer aller Datenbanken:

Get-MailboxDatabase `
     | ForEach-Object {`
        Add-ADPermission `
            -Identity $_.DistinguishedName `
            -User SVCUser `
            -ExtendedRights ms-Exch-EPI-May-Impersonate`
     }

Der Benutzer muss also auf dem CAS-Server das Recht bekommen, überhaupt Impersonation anfordern zu können und auf der Postfachdatenbank die Erlaubnis, mit Impersonation auf die Daten darin zuzugreifen. Das Konto darf zudem kein Administrator sein, da über die Gruppe der Administratoren auch hier wieder ein "DENY" dieses Rechte unterbinden würde.

Wenn die Vergabe von Berechtigungen auf der Datenbank zu weit gehen, kann natürlich ebenfalls über die Benutzer die Berechtigungen vergeben:

Add-ADPermission `
   -Identity "Mailbox"`
   -User SVCUser `
   -extendedRight ms-Exch-EPI-May-Impersonate

Hiermit kann dann das Dienstkonto auf das Postfach zugreifen.

Diese Funktion wird z.B. auch bei der Transporter Suite eingesetzt, damit diese alle Nachrichten in die Exchange Postfächer übertragen kann.

Wenn Sie nun über EWS diese Funktion nutzen wollen, dann müssen Sie natürlich den Web Services über Impersonation konfigurieren. hier ein Auszug:

ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.SID,wert)
ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.PrincipalName,wert)
ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.SmtpAddress,wert)
ewsservice.HttpHeaders.Add("X-AnchorMailbox", targetSmtp);

Beim Zugriff per EWS und Impersonation ist es essentiell wichtig, die AnchroMailbox mit anzugeben. Ansonsten wird EWS die Anfrage über den Postfachserver des angemeldeten Benutzers leiten und nicht direkt zu Zielpostfach.

Impersonation in den Protokollen

Sie können über die Einrichtung zwar genau vorhersagen, auf welche Postfächer von welchem Dienstkonto mittels Impersonate zugegriffen werden kann. Aber das heißt noch nicht, dass dies auch erfolgreich ist und in welcher Intensität dies erfolgt.

Seit Exchange 2007 gibt es neben den IISLogs für die allgemeinen Zugriffe per HTTPS auch die entsprechende Protokoll-Logs in C:\Program Files\Microsoft\Exchange Server\V??\Logging. Hier gibt es auch ein EWS-Verzeichnis, in denen in CSV-Dateien sehr umfangreiche Daten protokolliert werden. Sie können diese Dateien einfach per Import-CSV in PowerShell auswerten, da Exchange als erste Zeile den Header addiert. Da es im Kern aber wohl immer noch ein IISLog-Style" ist, müssen Sie die Kommentarzeilen überspringen. Das macht Import-CSV leider nicht. Ein Datensatz sieht dann z.B. wie folgt aus.

DateTime                         : 2017-06-20T03:00:53.690Z
RequestId                        : 12345678-1234-1234-1234-1234567890ab
MajorVersion                     : 15
MinorVersion                     : 1
BuildVersion                     : 669
RevisionVersion                  : 32
Ring                             : Unknown
ClientRequestId                  :
AuthenticationType               : Negotiate
IsAuthenticated                  : true
AuthenticatedUser                : svc-webcon@msxfaq.de
Organization                     : msxfaq.de 
UserAgent                        : Mozilla/4.0 (compatible; MSIE 6.0; MS WebServices Client Protocol 4.0.30319.36366)
VersionInfo                      : Target=None;Req=Exchange2013/Exchange2013;
ClientIpAddress                  : 192.168.100.55
ServerHostName                   : EX01
FrontEndServer                   : EX01.msxfaq.de
SoapAction                       : FindFolder
HttpStatus                       : 200
RequestSize                      : 999
ResponseSize                     :
ErrorCode                        :
ImpersonatedUser                 : User1@msxfaq.de
ProxyAsUser                      :
ActAsUser                        :
Cookie                           : 12345678901234567890123456789012
CorrelationGuid                  : 12345678-1234-1234-1234-1234567890ab
PrimaryOrProxyServer             : PrimaryServer
TaskType                         : LocalTask
RemoteBackendCount               : 0
LocalMailboxCount                : 1
RemoteMailboxCount               : 0
LocalIdCount                     : 1
RemoteIdCount                    : 0
BeginBudgetConnections           : 0
EndBudgetConnections             : 1
BeginBudgetHangingConnections    : 0
EndBudgetHangingConnections      : 00:04:00.1296040
BeginBudgetAD                    :
EndBudgetAD                      :
BeginBudgetCAS                   :
EndBudgetCAS                     :
BeginBudgetRPC                   :
EndBudgetRPC                     :
BeginBudgetFindCount             :
EndBudgetFindCount               :
BeginBudgetSubscriptions         : 0 MaxSub:5000
EndBudgetSubscriptions           : 0 MaxSub:5000
MDBResource                      :
MDBHealth                        :
MDBHistoricalLoad                :
ThrottlingPolicy                 : GlobalThrottlingPolicy_12345678-1234-1234-12
ThrottlingDelay                  : 0
ThrottlingRequestType            : [C]
TotalDCRequestCount              : 0
TotalDCRequestLatency            : 0
TotalMBXRequestCount             : 2
TotalMBXRequestLatency           : 0
RecipientLookupLatency           :
ExchangePrincipalLatency         :
HttpPipelineLatency              : 3
CheckAccessCoreLatency           : 0
AuthModuleLatency                :
CallContextInitLatency           : 0
PreExecutionLatency              : 9
CoreExecutionLatency             : 4
TotalRequestTime                 : 16
DetailedExchangePrincipalLatency :
ClientStatistics                 :
GenericInfo                      : App_BeginReq_Start=0;App_BeginReq_End=0;Back
                                   EndAuthenticator=WindowsAuthenticator;TotalB
                                   ERehydrationModuleLatency=0;CSCWTI=0;CSCWTI=
                                   0;cpn=RUM_ABR/RUM_ABRC/ABR/APAR/EWS_CE/EWS_C
                                   EC/APSRH/APRHE/AER/AERC/;cpv=0/0/0/2/10/15/1
                                   6/16/16/17/;MailboxTypeCacheSize=59011;S:Asp
                                   DispatchLatency.BeginRequest=0;S:ServiceTask
                                   Metadata.ADCount=0;S:AspDispatchLatency.EndR
                                   equest=0;S:ServiceTaskMetadata.ADLatency=0;S
                                   :ServiceTaskMetadata.RpcCount=2;S:ServiceTas
                                   kMetadata.RpcLatency=3;S:ServiceTaskMetadata
                                   .WatsonReportCount=0;S:WLM.Bal=299988 2;S:Se
                                   rviceTaskMetadata.ServiceCommandBegin=9;S:Se
                                   rviceTaskMetadata.ServiceCommandEnd=15;S:Act
                                   ivityStandardMetadata.Component=Ews;S:WLM.BT
                                   =Ews;S:BudgetMetadata.MaxConn=27;S:BudgetMet
                                   adata.MaxBurst=300000;S:BudgetMetadata.Begin
                                   Balance=300000;S:BudgetMetadata.Cutoff=0;S:B
                                   udgetMetadata.RechargeRate=1800000;S:BudgetM
                                   etadata.IsServiceAct=False;S:BudgetMetadata.
                                   LiveTime=00:04:00.1139757;S:BudgetMetadata.E
                                   ndBalance=299988;Dbl:WLM.TS=16;Dbl:ST.T[E
                                   X01.7b475535-a572-4073-b90a-2c3feb0072dd]=1;
                                   I32:RPCSVR.C[EX01.7b475535-a572-4073-b90a
                                   -2c3feb0072dd]=2;F:RPCSVR.AL[EX01.7b47553
                                   5-a572-4073-b90a-2c3feb0072dd]=0;I32:MB.C[
                                   EX01.7b475535-a572-4073-b90a-2c3feb0072dd]=
                                   2;F:MB.AL[EX01.7b475535-a572-4073-b90a-2c
                                   3feb0072dd]=1.5;Dbl:BudgUse.T[]=19.628299713
                                   1348;Dbl:MAPI.T[EX01.7b475535-a572-4073-b
                                   90a-2c3feb0072dd]=3;I32:RPCDB.C[EX01.7b47
                                   5535-a572-4073-b90a-2c3feb0072dd]=2;F:RPCDB.
                                   AL[EX01.7b475535-a572-4073-b90a-2c3feb007
                                   2dd]=0;Dbl:CCpu.T[CMD]=15.625;Dbl:RPC.T[E
                                   X01.7b475535-a572-4073-b90a-2c3feb0072dd]=3;
                                   I32:RPC.C[EX01.7b475535-a572-4073-b90a-2c
                                   3feb0072dd]=2;Dbl:EXR.T[EX01.7b475535-a57
                                   2-4073-b90a-2c3feb0072dd]=2;I32:MAPI.C[NAWEX
                                   16.7b475535-a572-4073-b90a-2c3feb0072dd]=8;I
                                   32:ROP.C[EX01.7b475535-a572-4073-b90a-2c3
                                   feb0072dd]=283749086
AuthenticationErrors             :
GenericErrors                    :
Puid                             :
StartTime                        : 2017-06-20T03:00:53.674Z
ProcessId                        : 3132
TimeInGC                         :
StartTotalMemory                 : 194540176
EndTotalMemory                   : 195861552
StartGCCounts                    : 280293_33047_4960
EndGCCounts                      : 280293_33047_4960
TokenBasedThrottlingPolicy       :
BudgetKey                        :
CoinsCharged                     :
CoinsChargedMethod               :
SidBudgetInfo                    :
AppBudgetInfo                    :
TenantBudgetInfo                 :
ResourceAccessed                 :
ResourceHealthBasedThreshold     :
ThrottledBy                      :
BackoffHint                      :
WorkClassification               :

Interessant sind hier die folgenden Felder, die hier nur teilweise gefüllt sind.

AuthenticatedUser                : svc-webcon@msxfaq.de
ImpersonatedUser                 : User1@msxfaq.de
ProxyAsUser                      :
ActAsUser                        :

Das ist dann schon ein sehr starkes Argument, dass hier ein Zugriff per Impersonation stattgefunden hat. CSV-Dateien lassen sich natürlich besonders einfach auch in PowerBI oder anderen Tools auswerten, so dass Sie sogar Datenmengen, Antwortzeiten, Client-IPs etc. filtern können. Hier ein Beispiel:

get-item "C:\Program Files\Microsoft\Exchange Server\V15\Logging\Ews\Ews_*.LOG" `
| % {import-csv $_} `
| ? {$_.authenticatedUser -ne $_.impersonatedUser} `
| ft datetime,AuthenticatedUser,ImpersonatedUser,Useragent,ClientIPAddress

DateTime                AuthenticatedUser       ImpersonatedUser UserAgent               ClientIpAddress
--------                -----------------       ----------------        ---------               ---------------
#Fields: DateTime       AuthenticatedUser       ImpersonatedUser UserAgent               ClientIpAddress
2017-06-12T06:00:56.... CRMSync@msxfaq.de User2@msxfaq.de         CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:00:59.... CRMSync@msxfaq.de User1@msxfaq.de         CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:02:10.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:02:35.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:06:02.... CRMSync@msxfaq.de User2@msxfaq.de         CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User2@msxfaq.de         CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User2@msxfaq.de     CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:02.... CRMSync@msxfaq.de User1@msxfaq.de    CRM/8.0.0.0/On-Prem   192.168.100.64
2017-06-12T06:06:03.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:06:27.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:06:44.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:06:50.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:08:25.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:08:30.... NT AUTHORITY\SYSTEM     SystemMailboxbb558c3... ExchangeServicesClie... fe80::c576:b2c3:f631...
2017-06-12T06:09:31.... NT AUTHORITY\SYSTEM     Christian.Miesner@ne... Exchange/15.1.669.32... fe80::c576:b2c3:f631...
2017-06-12T06:09:33.... NT AUTHORITY\SYSTEM     Christian.Miesner@ne... Exchange/15.1.669.32... 192.168.100.33
2017-06-12T06:09:40.... NT AUTHORITY\SYSTEM     Christian.Miesner@ne... Exchange/15.1.669.32... fe80::c576:b2c3:f631...

Die Liste können Sie mit Export-CSV natürlich wieder in eine Datei zur weiteren Verwertung schreiben lassen.

EWS Impersonation im Eventlog

Wenn Sie im Exchange Eventlog die Protokollierung anheben, dann finden Sie auch die Zugriffe im Eventlog:

Set-EventLogLevel "MSExchange Web Services\Core" -Level expert

Im Application Eventlog finden Sie dann Einträge wie:

Log Name:      Application
Source:        MSExchange Web Services
Date:          1/29/2019 5:36:56 PM
Event ID:      23
Task Category: Core
Level:         Information
Keywords:      Classic
User:          N/A
Computer:      EX2016.msxfaq.de
Description:
The access token used for Exchange impersonation includes the following SIDs: 

User: 
S-1-5-21-1454471165-1234567890-123456789-12273    MSXFAQ\user1

Group: 
S-1-5-21-1454471165-1234567890-123456789-66100    MSXFAQ\Group1
S-1-5-21-1454471165-1234567890-123456789-66101    MSXFAQ\Group2
S-1-5-21-1454471165-1234567890-123456789-66103    MSXFAQ\Group3
S-1-1-0    Everyone
S-1-5-11    NT AUTHORITY\Authenticated Users 

Restricted Group:

So können Sie ebenfalls ermitteln, wann ein Zugriff per EWS Impersonation erfolgt ist.

EWS und Delegate Access

Ich möchte dennoch nicht den Weg verheimlichen, mit dem Sie einem Dienstkonto auch Zugriffe auf ausgewählte Ordner eines Postfachs geben können. Eine Software kann per EWS auch problemlos auf andere Postfächer und Ordner zugreifen, solange es die entsprechenden Rechte dazu hat. Diese Rechte kann der Anwender selbst einrichten oder ein Exchange Administrator per PowerShell. Anders als aber EWS-Impersonation sieht der Anwender die Berechtigungen für das Dienstkonto und kann sie auch wieder ändern, d.h. auch wegnehmen und ihre zentrale Lösung entsprechend stören.

Interessanterweise reicht es z.B. für den Zugriff auf Kalender oder Kontakte dem Dienstkonto auch nur den Zugriff auf diese Ordner zu erlauben. Es ist also nicht erforderlich auch auf die Wurzel des Postfachs entsprechende Rechte zu vergeben. Allerdings habe ich das nur mit "predefined" Ordnern versucht, d.h. wirklich die Default Ordner wie eben den Kalender. Wenn der Benutzer weitere Ordner angelegt hat und ich den Weg dorthin nicht kenne und daher durchlaufen muss, dann werde ich um Rechte auf dem Weg dort hin nicht umhin kommen.

Bedenken Sie bei der Vergabe der Rechte per PowerShell dran, dass der Name der Ordner durchaus "sprachabhängig" sein kann. Ich habe ich daher eines Tricks bedient, um die Struktur des Postfachs zu lesen.

$FolderName = (Get-MailboxFolderStatistics -Identity $smtpaddress |where {$_.FolderType -eq 'Calendar'}).Name

So habe ich den "Namen" und kann mir die Identity dann zusammenbauen:

Get-MailboxFolderPermission -Identity ($smtpaddress + ":\" + $FolderName) -User $delegateUser

Mit entsprechenden Rechten geht auch ein Get-MailboxFolder.

Der große Vorteil dieser selektiven Vergabe von Rechten besteht darin, dass das Dienstkonto sich eben nicht "als User" ausgeben kann ud quasi in dessen Eigenschaft dann auch alles ändern, Mails senden etc. kann, ohne dass dies unterschieden werden kann. Wenn ein Programm als Dienstkonto über diese eingeschränkten Rechte arbeitet, dann kann es keine Mails senden aber auch von ihm angelegte Termine haben das Dienstkonto als "Owner". Outlook und Exchange unterscheiden genau, ob ein Konto später nur "seine" oder "alle" Termine bearbeiten darf. Das ist speziell bei gemeinsam genutzten Ordnern zu beachten.

Weitere Links