Einführung in OAuth2.0 und OpenID Connect im .NET Technologie-Stack
Ein Fachbeitrag von Lucas Ratay, Software Developer
Seiteninhalt
Problematik ohne diese Standards
Folgendes ist eine im Internet sehr häufig auftretende Situation: Ein Nutzer besitzt bei einem beliebigen Social-Media-Dienst ein Nutzerkonto. Bei diesem Dienst hat der Nutzer Daten – zum Beispiel Bilddateien – hochgeladen. Der Nutzer möchte einer Drittanwendung Zugriff auf diese Daten gewähren.
Da es hierfür keine bessere Lösung gab, wurde dieses Problem in den dunklen Zeiten des Internets durchaus dadurch gelöst, dass der Nutzer einfach der Drittanwendung seine Zugangsinformationen übergeben hat. Diese hat sich damit als Nutzer beim Dienst authentifiziert und konnte somit den Zugriff auf die betroffenen Daten erhalten. Hieraus ergibt sich eine Reihe von Problemen.
Da die Drittanwendung als der Nutzer agiert, kann der Dienst diese nicht vom Nutzer unterscheiden. Die Drittanwendung hat also alle Berechtigungen, die der Nutzer auch hat. Es kann keine Eingrenzung stattfinden und es ist nicht möglich, nur einer der Drittanwendungen diese Berechtigungen zu entziehen.
Der zweite große Aspekt stellt konkrete Sicherheitsprobleme dar. Das Passwort muss für diesen Anwendungsfall rekonstruierbar (als Klartext oder verschlüsselt) vorgehalten werden. Dies ist aus Sicherheitsgründen nicht vertretbar. Zusätzlich ist das Passwort an mehreren Stellen vorhanden, was das Risiko der Kompromittierung erhöht. Wird das Passwort an einer Stelle kompromittiert, wirkt sich dies auf Nutzer, Dienst und alle Drittanwendungen aus.
Diese Probleme sollen durch die Standards OpenID Connect und OAuth2.0 behoben werden.
Lösungsansatz
Der OAuth-Standard löst dieses Problem, indem er Drittanwendungen und den Nutzer voneinander trennt. Dies wird erreicht, indem die Drittanwendung für die Authentifizierungsstelle eine eigene Entität darstellt. Die Drittanwendung muss also dem Identity Provider bekannt sein, sich gesondert vom Nutzer authentifizieren lassen und kann damit auch gesonderte Berechtigungen erhalten. Um den API-Zugriff zu realisieren, führt OAuth ein Token ein, welches als Schlüssel für gesicherte Ressourcen agiert sowie zusätzlich Informationen aller Art enthalten kann.
Terminologie
Resource Owner
- Nutzer, der die Berechtigung für bestimmte Ressourcen besitzt und diese anderen gewähren kann
- Client Third-Party-Anwendung, welche Zugriff auf Ressourcen des Resource Owners erlangen möchte
- Resource Server Server, auf welchem sich die Daten des Resource Owners befinden
- Identity Provider Server, welcher die Authentifizierung, Autorisierung und Ausstellung von Tokens vornimmt
Access Token
- JSON Web Tokens. Base64-enkodierte JSON-Objekte inklusive Header und Checksumme, genutzt als Schlüssel für die Authentifizierung
- Claims Schlüssel-Wert-Paare, die Informationen über den Nutzer oder Client enthalten
- Scopes Berechtigungen auf Ressourcen, die vom Client angefordert werden können
Ablauf des OAuth2.0-Flows
Im OAuth-Standard sind vier verschiedene mögliche Abläufe zur Authentifizierung definiert, sogenannte „Flows“. Relevant für den Nutzer ist allerdings nur einer davon. Andere sind für die Client-Anwendung reserviert oder sollten nicht mehr eingesetzt werden, da diese Abstriche bei der Sicherheit machen, um Clients mit limitierten Möglichkeiten zu unterstützen. Solche Clients sollten heutzutage nicht mehr vorkommen. Der relevante Flow ist der sogenannte „Authorization Code Grant“.
Der Fall ist der gleiche wie im vorherigen Beispiel, der Nutzer möchte dem Client einen Zugriff auf seine Ressourcen gewähren.
Zu diesem Zweck führt der Client für den Nutzer einen Redirect zum Identity Provider durch. Im Query des Redirects sind Credentials des Clients vorhanden und die Scopes, die dieser anfordert.
Anschließend wird der Nutzer vom Identity Provider authentifiziert und kann festlegen, welche Berechtigungen der Client erhalten soll.
Der Nutzer wird nach erfolgter Authentifizierung zum Client zurückgeleitet. Hierbei wird dem Client ein sogenanntes Grant Token übergeben. Mit diesem kann der Client dann über den Backchannel, also über einen POST-Request, ein Access Token anfordern. Dessen Gültigkeit ist zeitlich begrenzt. Wird das Access Token also kompromittiert, kann es nur zeitlich begrenzt unberechtigt genutzt werden.
OAuth2.0 Probleme
OAuth löst also viele Probleme, bringt aber auch neue mit sich.
Im OAuth-Standard ist nicht festgelegt, welche Nutzerinformationen der Client enthält. Das ist aber zum Beispiel nötig, um einen Single Sign-on zu realisieren. Dies wurde daher von jedem Anbieter unterschiedlich realisiert und hat dafür gesorgt, dass OAuth anbieterspezifisch genutzt werden musste, was solch einen Standard ad absurdum führt. Zur Lösung dieser Probleme wurde der Standard OpenID Connect ins Leben gerufen.
OpenID Connect
OpenID Connect erweitert den OAuth2.0-Standard um Möglichkeiten, standardisiert Informationen über den Nutzer zu erhalten. Dies wird mithilfe eines zusätzlichen Tokens, dem sogenannten Identity Token, und einer erweiterten API zum nachträglichen Anfragen von Daten realisiert.
Des Weiteren führt der Standard einen zusätzlichen Flow, den sogenannten Hybrid Flow, ein. Dieser Flow sendet die beiden Tokens bei unterschiedlichen Requests an den Client und modifiziert den Ablauf, um zusätzliche Angriffsmöglichkeiten zu verhindern.
Außerdem verlangt der Standard ein Discovery-Dokument, welches ausführliche Informationen über vorhandene Endpoints, Schnittstellen, existierende Rechte und mögliche Informationen über die Nutzer enthält.
Identity Server
Um einen OAuth2.0 und OpenID Connect-fähigen Server selbst zu implementieren, gibt es im .NET-Umfeld ein Standardprodukt, den sogenannten Identity-Server. Der Identity-Server ist kostenlos, der Quelltext als Open-Source verfügbar. Die Core-Bibliothek, Erweiterungen und Templates sind unter die Apache-Lizenz 2.0 gestellt. Mit dieser Lizenz ist ein Einsatz im produktiven Umfeld bedenkenlos möglich.
Der Identity-Server ist eine sogenannte Provider-Library. Das heißt, der Identity-Server ist keine eigenständige Server-Anwendung, muss allerdings auch nicht vom Programmierer für Aktionen angesprochen werden, sondern registriert seine HTTP-Endpunkte selbstständig. Dies hat den Vorteil, dass der Identity-Server ohne großen Programmieraufwand in existierende Anwendungen integriert werden kann.
Der Identity-Server ist für OpenID Connect, und somit auch für OAuth2.0, offiziell zertifiziert und setzt sich in seiner Verbreitung auch programmiersprachenübergreifend gegen vergleichbare Technologien durch.
Als kostenpflichtige Leistungen werden Schulungen, Support für die Entwicklung und das Betreiben des Servers, die Erweiterung des Servers um den SAML-Standard sowie eine UI-Anwendung zur Verwaltung des Servers angeboten.
Auf der Webseite des Identity-Servers findet sich eine ausführliche Dokumentation und es werden umfangreiche Quickstart-Projekte angeboten, mit denen es möglich ist, einen solchen Server in kurzer Zeit umzusetzen.
Auf Datenbankseite werden nativ alle Datenbanken unterstützt, die an den bekannten OR-Mapper Entity Framework für .NET per Treiber (Database Provider) angeschlossen werden können. Will man eine gänzlich eigene Datenschnittstelle realisieren, reicht es, einige Interfaces zu implementieren und dem Identity-Server anzugeben.