← Zur ├ťbersicht

Impersonation mit Active Directory Protocol Transition ­čôÜ

Einleitung

Impersonation ist notwendig, so dass alle Aktionen einer Anwendung im Rahmen des Benutzers ausgef├╝hrt werden. Dies ist notwendig, um ├änderungen am Datenbestand protokollieren zu k├Ânnen und unberechtigten Zugang auf u.a. einen SQL-Server verhindern zu k├Ânnen. ├änderungen am Datenbestand sollen protokolliert und Berechtigungen auf Systemebene gepr├╝ft werden. F├╝r Dateisysteme und SQL Server bedeutet dies unter Windows, dass die Applikation im Kontext des Benutzers aus dem Active Directory ausgef├╝hrt wird.

  • M├Âglichkeit zur Protokollierung im SQL Server (Audit)
  • Berechtigungspr├╝fung auf System-Ebene f├╝r Dateien und SQL Server

Im Zuge eines Kundenprojekts begutachteten wir das Kerberos-Protokoll, um eine Ticket-Delegation gew├Ąhrleisten zu k├Ânnen. Dieser Artikel stellt die gesammelten Erkenntnisse und L├Âsungsans├Ątze vor.

Wir setzen einen IdentityServer ein, um ein OAuth2-Token auszustellen, nachdem die Identit├Ąt des Benutzers gegen das Active Directory gepr├╝ft wurde. Mitgelieferte valide Credentials und die Mitgliedschaft in einer bestimmten Gruppe legitimieren die Anmeldung eines Clients.

Microservices sind untereinander sehr kommunikativ. Ein separat stehender IAM-Microservice dient anderen Services dazu, Rechte im Kontext der Applikation einzufordern. Auch UseCases aggregieren verschiedene Aufrufe zu Microservices. Dadurch entstehen die ersten Multi-Hops in unserer Architektur... und die ersten Probleme gleich dazu.

Theorie

Protokolle zur Anbindung an ein Active Directory

Der IIS befragt auf Anfrage eines Clients den Kerberos ├╝ber das GSSAPI-Protokoll [1] nach geeigneten Authentifizerungsprotokollen (SPNEGO-Feature) und bekommt eine Auswahl an m├Âglichen Protokolle zur├╝ck.

Kerberos-Protokoll

Die Kerberos-Authentifizierung findet ├╝ber einen "Key Distribution Center"-Service (KDC) statt. Der Client holt sich mit seinen Credentials ein Ticket ab, das als "Forwardable" gekennzeichnet ist und schickt dieses an den Server. Der Server besorgt sich aus dem KDC nun selbst ein Ticket, das als "Delegierbar" gekennzeichnet ist. Dieses Ticket kann genutzt werden, weitere Dienste zu befragen und sich dort als der urspr├╝ngliche Benutzer ├╝ber das Kerberosprotokoll anzumelden.

"NT Lan Manager"-Protokoll (NTLM)

Die NTLM-Authentifizierung ben├Âtigt die Credentials des angefragten Benutzers, um eine vom Server ausgestellte Challenge zu beantworten. Da die Credentials nach der Anmeldung an einem Server nicht mehr zur Verf├╝gung stehen, kann kein weiterer externer Dienst mehr angefragt werden.

Delegation

Eine Delegationskette kann ├╝ber andere Services aufgebaut werden, um eine Identit├Ąt durchschleifen zu k├Ânnen. Mehrere M├Âglichkeiten stehen zur Verf├╝gung, um dies unter der Schirmherrschaft eines Active Directory zu bewerkstelligen.

Unconstrained Delegation ├╝ber Kerberos

Eine Delegationskette startet beim Endbenutzer und kann ├╝ber beliebige Services aufrecht erhalten werden. Dies funktioniert so lange, wie Kerberos als Protokoll genutzt werden kann.

Constrained Delegation ├╝ber Kerberos

Eine Delegationskette startet beim Endbenutzer und kann ├╝ber vorher festgelegte Services aufrecht erhalten werden. Dies funktioniert so lange, wie Kerberos als Protokoll genutzt werden kann.

Constrained Delegation ├╝ber arbitrare Protokolle (Protocol Transition)

Eine Delegation startet bei einem aufgerufenen Service und wird mit einen dazu berechtigen technischen Benutzer realisiert, jedoch kann sie nur f├╝r vorher festgelegte Services aufgebaut werden. Der Endbenutzer muss sich nicht ├╝ber das Kerberos-Protokoll authentifizieren.

Bisheriger Ansatz

Bisher hielten wir die Delegation f├╝r intakt, weil die Zugriffe auf externe Ressourcen funktioniert haben, f├╝r die Windows-Anmeldungen vorausgesetzt werden. Dies war jedoch nur der Fall, weil es sich bei dem ApplicationPool-Benutzer einen technischen Benutzer mit entsprechenden Rechten handelte.

Schaubild zum bisherigen Ansatz

Die Delegationskette war somit unterbrochen und liess sich nicht wiederherstellen, weil schwerwiegende H├╝rden im Weg standen:

  • Double-Hops ├╝ber einen Loopback benutzen NTLM.
  • Authentifizierung ├╝ber IdentityServer und Kerberos funktionieren nicht ohne Nachhilfe parallel.
  • Clients ohne Unterst├╝tzung f├╝r Windows-Authentifizierung funktionieren nicht.
  • Das Advanced Message Queuing Protocol (AMQP) soll funktionieren.

Dies wollen wir nachfolgend im Detail analysieren.

Double-Hop ├╝ber einen Loopback benutzen NTLM

Ist die Delegation bei allen teilnehmenden Services korrekt konfiguriert, bleibt die Delegationskette automatisch intakt. Eine ├ťberpr├╝fung kann im Microservice stattfinden, indem der Impersonierungslevel lokal gepr├╝ft wird. Bei intakter Delegationskette wird dies explizit als Delegation angezeigt, ansonsten sinkt der Level auf Impersonation ab:

public void GetImpersonationLevelForCurrentIdentity()
{
    var currentIdentity = System.Security.Principal.WindowsIdentity.Current;
    return currentIdentity.ImpersonationLevel.ToString();
}

Findet ein Double-Hop auf einen lokalen Service statt, greifen interne Sicherheitsmechanismen und schr├Ąnken die Protokollauswahl so ein, dass die Delegationskette unterbrochen wird. Folgende Abbildung zeigt die korrekte Autorisierung ├╝ber Kerberos (Rot hinterlegt) und den Fallback auf NTLM beim zweiten Hop (Gr├╝n hinterlegt):

Schaubild zur Double-Hop-Problematik

Im Internet rar zu findende, diskutierte Ans├Ątze sind von offizieller Seite unbest├Ątigt, mit deutlichen Warnungen versehen oder funktionieren nicht wie angek├╝ndigt. Der Ansatz, pauschal ├╝ber einen extern liegenden Proxy zu gehen, wurde aufgrund der steigenden Komplexit├Ąt und verringerten Performance verworfen. [[2]] [3]

Authentifizierung ├╝ber IdentityServer und Kerberos funktionieren nicht ohne Nachhilfe parallel

  • Beide Mechanismen verwenden den Authorize-Header aus der Request.
  • Das HTTP-Protokoll unterst├╝tzt nur einen Authorize-Header pro Request.

Workaround:

  1. Ein Workaround schickt den Token als "Alternative-Authorization"-Header mit.
  2. Nachdem der IIS die Identit├Ąt aufgel├Âst hat, werden in der ersten Middleware die Header getauscht.
  3. Die IdentityServer-Middleware l├Âst den Token auf und erstellt eine zweite Identit├Ąt unter dem existierenden WindowsPrincipal.
/// <summary>
/// Switches alternative authorization headers for subsequent middleware to preserve impersonation.
/// </summary>
/// <seealso cref="OwinMiddleware" />
public class AlternativeAuthorizationMiddleware : OwinMiddleware
{
    [...]

    /// <summary>
    /// Process an individual request.
    /// </summary>
    /// <param name="context">The OWIN context.</param>
    /// <returns>An async task.</returns>
    public override Task Invoke(IOwinContext context)
    {
        var requestHeaders = context.Request.Headers;

        if (requestHeaders.ContainsKey("Alternative-Authorization"))
        {
            var alternativeAuthorizationHeader = requestHeaders["Alternative-Authorization"];

            requestHeaders.Remove("Alternative-Authorization");
            requestHeaders.Set("Authorization", alternativeAuthorizationHeader);

            this.Logger.Info(string.Empty, "Found alternative authorization header; switched headers.");
        }

        return this.Next.Invoke(context);
    }
}

Clients ohne Unterst├╝tzung f├╝r Windows-Authentifizierung funktionieren nicht

Ein Client muss Kerberos/NTLM unterst├╝tzen, um die Windows-Authentifizierung des IIS benutzen zu k├Ânnen. Damit entf├Ąllt die Verwendung diverser anderer Clients (z.B. Postman, SAP, MATLAB), deren Benutzung aufgrund der fachlichen Anforderungen m├Âglich sein muss.

Das Advanced Message Queuing Protocol (AMQP) soll funktionieren

Auch wenn REST-Schnittstellen ein einfaches, weit verbreitetes und definitiv akzeptiertes Konzept darstellt, sind wir von der Flexibilit├Ąt und Performance von AMQP ├╝berzeugt. Langfristig steht somit der Plan, dieses Protokoll vermehrt in diesem Kundenprojekt einzusetzen. Die gesamte L├Âsung wurde aktuell RESTful realisiert und m├╝sste auch so bleiben. Die Authentifizierungsmechanismen des IIS greifen bei einem AMQP-Broker sowieso nicht.

L├Âsungsansatz zur Adressierung der offen Fragestellungen

Lokale Multi-Hops sind ein fester Bestandteil unserer Architektur; somit k├Ânnen wir die Probleme nicht umschiffen. Aus diesen Gr├╝nden wird der bisherige Ansatz verworfen und ein neuer wird gew├Ąhlt, bei dem sowohl unsere Anforderungen abgedeckt werden als auch die genannten H├╝rden der Vergangenheit angeh├Âren.

Der aktuelle Ansatz droppt die Unterst├╝tzung von Ticket-Forwarding ├╝ber Kerberos f├╝r eine sogenannte Protocol Transition. Hier erhalten die Backends die M├Âglichkeit, eine Impersonierung durchzuf├╝hren, ohne ein Ticket von einer Identit├Ąt ├╝bermittelt bekommen zu haben. Aus dem OAuth2-Token, der als abgesichert gilt, extrahiert das Backend den sogenannten UserPrincipalName (UPN) als notwendige Information, um welchen Benutzer aus dem Active Directory es sich handelt.

Schaubild zum aktuellen Ansatz

Erweiterung des IdentityServer

Im Zuge der Umsetzung dieses Ansatzes erh├Ąlt der IdentityServer die Unterst├╝tzung f├╝r eine weitere Autorisierungsart:

Eine ├╝ber Kerberos abgesicherte Verbindung ist eine implizite Authentifizierung gegen├╝ber dem IdentityServer. Die Anmeldung in einer Windows-Sitzung und die Verf├╝gbarkeit einer Session gilt als Ersatz f├╝r die ├ťbermittlung der Credentials. Der Login-Dialog im Client wird daher ebenfalls entfallen, bzw. f├╝r die Nutzung eines abweichenden Kontos oder eines alternativen Clients manuell aufrufbar sein.

Erweiterungen der Infrastruktur

Da die Windows-Identit├Ąt rekonstruiert wird, bedarf es dem gesamten Kerberos-Handshake im IIS nicht mehr. Die Impersonierung findet nun explizit statt und unterliegt der Kontrolle einer Anwendung.

Fazit

Es ergeben sich deutliche Vorteile bei diesem Vorgehen:

  • Es stehen weitere Clients zur Verf├╝gung (Postman, SAP, MATLAB).
  • Ein Kerberos-Token kann mehrere hundert Kilobytes gro├č sein, darum wird jeder Request schlanker.
  • Die Komplexit├Ąt des Prozesses und somit auch des Quellcodes sinkt.
  • Verlagerung der Impersonierungsmechanik von der Infrastruktur in den Applikationscode (Hostunabh├Ąngig und damit zukunftssicher).

Zwar entf├Ąllt die M├Âglichkeit, eine ├╝ber Protocol Transition erlangte Identit├Ąt an weitere Services weiterzuleiten. Die Services sind dagegen selbst previlegiert, eine Impersonierung durchzuf├╝hren.

Realisierung an einem Beispielszenario

Schaubild zum Beispielszenario

Die Realisierung gliedert sich in einzelne einfache Schritte:

How-To: Konfiguration des Active Directories f├╝r Protocol Transition

SPNs registrieren

Die Konfiguration, welche Dienste f├╝r eine Delegierung bereit stehen, wird ├╝ber einen sogenannten ServicePrincipalName (SPN) bekannt gemacht. Die Verwaltung von SPNs geschieht mit dem SetSPN-Tool, das ab Werk mitgeliefert wird.

Dieser SPN besteht aus:

  • Einem wahlfreien Dienstbezeichner
  • Dem NetBios-Namen oder FQDN
  • Optional dem Port des Services
  • Dem Dom├Ąnenkonto

Eine SPN f├╝r den IIS-Host wird bereits beim Eintritt in die Dom├Ąne angelegt und ist f├╝r das Maschinenkonto registriert. Dies erlaubt die Verwendung der standardm├Ą├čig eingestellten AppPoolIdentity f├╝r jeden Application Pool. Wenn unterschiedliche Benutzer verwendet werden, muss dieser Eintrag ersetzt werden durch eine SPN mit definiertem Port.

Ein vom IIS entfernt liegender SQL Server muss daher auch als SPN hinterlegt werden, damit eine Delegation stattfinden kann.

Im folgenden f├╝r das Beispielszenario durchgef├╝hrt:

Host-Erreichbarkeit f├╝r Applikationsserver registrieren

SetSPN -C -S Host/wolf-win-dev.BluePrint.local win-dev$

Standardinstanz des SQL Servers f├╝r Applikationsserver registrieren

SetSPN -C -S MSSQLSvc/wolf-win-dev-2.BluePrint.local win-dev$

Andere SQL Server Instanz f├╝r Applikationsserver registrieren

SetSPN -C -S MSSQLSvc/wolf-win-dev-2.BluePrint.local:1433 win-dev$

Protocol Transition aktivieren und SPN zuweisen

Die Protocol Transition wird auf dem Benutzer- bzw. dem Maschinenkonto im Active Directory konfiguriert. Der Delegationstab steht erst zur Verf├╝gung, wenn f├╝r dieses Konto bereits SPNs existieren.

Schaubild zur Delegationskonfiguration

How-To: Konfiguration des IIS f├╝r Protocol Transition

AppPoolIdentity konfigurieren

Mit secpol.msc oder gpedit.msc in die lokalen Computerrichtlinien gehen und zu Computer Configuration/Windows Settings/Security Settings/Local Policies/User Rights Assigment navigieren.

Unter den Punkten m├╝ssen alle verwendeten AppPool-Benutzer hinzugef├╝gt werden:

  • Act as part of the operating system
  • Impersonate a client after authentication
  • Log on as a service
  • Replace a process level Token

Schaubild zur Einstellung der Sicherheitsrichtlinien

Der konstruierte Benutzer der standardm├Ą├čigen AppPoolIdentity wird ├╝ber "IIS APPPOOL\" referenziert. Dieser kann nicht durch Browsen gefunden werden, aber wird durch Eintippen erkannt. Das Erstellen eines neuen AppPools bzw. das Zuweisen eines AppPool-Benutzers reicht aus, um einige dieser Punkte automatisch vom System setzen zu lassen.

UseAppPoolCredentials

F├╝r den IdentityServer bleibt die Windows-Authentifizierung bestehen. Das bedeutet, dass ein Kerberos-Ticket zur Delegation f├╝r den AppPool-Benutzer ausgestellt wird und unter Zuhilfenahme dessen Credentials verschl├╝sselt wird. Dies erreicht man, indem im Konfigurationseditor der Webseite unter dem Pfad system.webServer/security/authentication/windowsAuthentication die Flag UseAppPoolCredentials gesetzt wird. [4]

Anonyme Authentifizierung

Die anonyme Authentifizierung erfordert keine Anmeldung. Dieses Feature wird im IIS oder ├╝ber die web.config gesteuert und bleibt f├╝r alle Apps au├čer dem IdentityServer aktiviert. Der IdentityServer ben├Âtigt eine Route zur Nutzung von Basic-Auth, f├╝r den die Authentifizierung deaktiviert wird, alle anderen Routen werden ├╝ber die Windows-Authentication gesch├╝tzt.

Windows-Authentication

Nach erfolgreicher Anmeldung des Clients ├╝ber das ausgehandelte Protokoll am IIS gilt der Benutzer als authentifiziert. Ein nicht authentifizierter Client wird abgewiesen, sofern keine anonyme Authentifizierung im IIS aktiviert ist. Dieses Feature wird im IIS oder ├╝ber die web.config gesteuert und bleibt nur f├╝r den IdentityServer aktiviert.

NTLM kann man als Methode deaktivieren, jedoch sollte das standardm├Ą├čige Negotiate-Protokoll statt der "Negotiate:Kerberos"-Auspr├Ągung verwendet werden. Dies erm├Âglicht weiterhin die Nutzung des Kernel-Modus zur Beantragung sowie Verwaltung eines Tickets und verbessert die Performance bei der Abhandlung der Handshakes deutlich.

ASP.NET-Impersonierung

Die Anmeldung des Clients am Server wird f├╝r die Aktivierung des ASP.NET-Moduls verwendet, sodass dieser Prozess im Kontext des urspr├╝nglichen Benutzers l├Ąuft. Dieses Feature wird im IIS oder ├╝ber die web.config gesteuert und bleibt nur f├╝r den IdentityServer aktiviert.

Middleware zur Impersonierung

Die Impersonierung sollte zentral gesteuert werden. Bestenfalls im Zuge der Auswertung des Tokens vom IdentityServer als darauf folgende Middleware. Somit ist die Delegation ohne weiteres Zutun f├╝r eine einzelne eingehende Anfrage aktiv und die Verantwortlichkeit wird von den einzelnen Microservices entkoppelt.

var impersonatedIdentity = new System.Security.Principal.WindowsIdentity("<UPN>");

using (var impersonationContext = impersonatedIdentity.Impersonate())
{
    [...]

    this.Next.Invoke(context);

    impersonationContext.Undo();
}

Useful Stuff

Warum kein C2WTS f├╝r Protocol Transition gebraucht wird?

Einige Artikel sprechen von einem lokalen Service, der auf dem Applikationsserver installiert und eingerichtet werden muss - dem sogenannten "Claims 2 Windows Token Service" (C2WTS). Mit der Integration der Windows Identity Foundation (WIF) in .NET 4.5 steht das Paket nun sofort zur Verf├╝gung und man muss zur Identit├Ątserstellung nicht mehr mit nativen APIs (LSA) oder einem separatem Dienst agieren. Der Konstruktor der WindowsIdentity-Klasse hat nun einen Konstruktor, der diese Aufgaben ├╝bernimmt. [5]

Identit├Ąt bei Benutzung von async/await weiterleiten

Die TPL im .NET-Framework bietet ausreichend Unterst├╝tzung, um eine Identit├Ąt ├╝ber Threadgrenzen weiterzuleiten. Mit einem SynchronizationContext kann sehr genau gesteuert werden, auf welchem Kontext die Threads agieren und auch zur├╝ckkehren. In ASP.NET verliert sich die Identit├Ąt als Standardverhalten aus Kompatibilit├Ątsgr├╝nden leider und es m├╝sste immer dieser Workaround angewandt werden. Mit dem async/await-Pattern verliert man aufgrund von Syntax-Zucker leider den Einfluss; doch kann diese Einstellung global beeinflusst werden. [6]

In der Datei %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet.config gibt es zwei Flags, die wie folgt gesetzt werden m├╝ssen:

<legacyImpersonationPolicy enabled="false" />
<alwaysFlowImpersonationPolicy enabled="true" />

Checken der SPNs eines Accounts

Mit dem Tool SetSPN l├Ąsst sich f├╝r SPNs auch eine Validit├Ątspr├╝fung (gegen Doppeleintr├Ąge) durchf├╝hren. Die erwartete Ausgabe ist eine Liste an Objekten mit duplizierten SPNs:

SetSPN -X

Desweiteren k├Ânnen alle registrierten SPNs f├╝r ein Dom├Ąnenkonto gelistet werden:

SetSPN -L <Account-Name>

Hinweis:

  1. Maschinenaccounts werden mit einem Dollarzeichen ($) als Suffix versehen.
  2. SPNs werden mittlerweile case-insensitive gepr├╝ft.

Verifizieren der Identit├Ąt auf einem SQL Server

Bei folgendem Query handelt es sich um einen einfachen Test, der von einer Demoanwendung ausgef├╝hrt werden kann, um den Impersonierungsstatus eines Datenbankaufrufs zu testen.

SELECT SYSTEM_USER AS [ExecutingUserName], ORIGINAL_LOGIN() AS [LoggedInUserName]

Wireshark

Wireshark kann beim Debuggen der Kommunikation unterst├╝tzen. Im Authorization-Header der HTTP-Schicht finden sich die GSSAPI-Eintr├Ąge und somit bspw. die angebotenen Authentifizierungsmethoden. Um die Loopback-Kommunikation analysieren zu k├Ânnen, muss erst Wireshark und danach der optionale NPCAP-Adapter installiert werden.

LSA- und SPNEGO-Logging aktivieren

Um den Anmeldeprozess verfolgen zu k├Ânnen, kann das Systemlogging aktiviert werden. Die entsprechenden Eintr├Ąge finden sich nach der Aktivierung in der Registry des DC-Controllers unter %WINDIR%\system32\lsass.log. Die Aktivierung sollte sp├Ąter wieder r├╝ckg├Ąngig gemacht werden, da es sich um ein verboses Logging handelt und die Dateigr├Â├če rasch anw├Ąchst.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"SPMInfoLevel"=dword:0000101F
"LogToFile"=dword:00000001
"NegEventMask"=dword:0000000F

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos]
"LogToFile"=dword:00000001
"LogLevel"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters]
"LogToFile"=dword:00000001
"LogLevel"=dword:00000001