OpenID Connect: Login mit OAuth, Teil 2: Identity-Federation und fortgeschrittene Themen

Mit den früher vorgestellten Funktionen von OpenID Connect sind die grundsätzlichen Anforderungen an ein Login und Single Sign-On auf einfache Art und Weise abgedeckt. Aber auch wenn die Anwendungsfälle komplizierter werden, hat OpenID Connect noch eine Menge zu bieten.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 20 Min.
Von
  • Torsten Lodderstedt
Inhaltsverzeichnis

Mit den früher vorgestellten Funktionen von OpenID Connect sind die grundsätzlichen Anforderungen an ein Login und Single Sign-On auf einfache Art und Weise abgedeckt. Aber auch wenn die Anwendungsfälle komplizierter werden, hat OpenID Connect noch eine Menge zu bieten.

Bisher wurde immer davon ausgegangen, dass eine Anwendung zu einem bestimmten OpenID Provider (OP) gehört. Da OpenID ein standardisiertes Protokoll ist, ist es aber auch möglich, darüber andere Nutzer "anzuzapfen" (Sicht der Anwendung) beziehungsweise die Reichweite der eigenen Identitäten zu erhöhen (Sichtweise des OP bzw. des Benutzers).

Dafür sei als Beispiel vorgestellt, dass Max aus dem früheren Artikel sich auf dem Nachrichtenportal des Anbieters News Corp registrieren möchte. Da er keine Lust hat, sich einen neuen Account anzulegen, will er stattdessen seinen Account bei der Fun Corp, seinem E-Mail-Anbieter, verwenden. Der Vorteil für die News Corp besteht darin, dass ein solches 3rd Party Login eine direkte Registrierung und Nutzung des Dienstes ohne lästiges Double Opt-in für die E-Mail-Adresse erlaubt. Obwohl News Corp und Fun Corp keine Geschäftsbeziehung unterhalten, lässt sich das gewünschte Szenario mit OpenID Connect implementieren.

Zuerst muss der potenzielle Client (hier News Corp) den OpenID Provider (hier der Autorisierungsserver von Fun Corp) suchen und herausfinden, unter welchen URLs die Endpunkte exponiert werden und welche Fähigkeiten von OpenID Connect dieser unterstützt. Hierzu spezifiziert OpenID Connect das sogenannte OpenID Connect Discovery, bei dem sich der OP und dessen Metadaten unter Nutzung der E-Mail-Adresse (oder anderer Daten) des Benutzers finden lassen. Der Ablauf soll anhand des Beispiels aus dem ersten Artikel
veranschaulicht werden.

Max' E-Mail-Adresse lautet bekanntlich "m.mustermann@funcorp.com". News Corp leitet aus dem Domain-Teil der E-Mail-Adresse die Adresse "https://funcorp.com" ab und sendet an diese Adresse einen sogenannten WebFinger-Request:

GET /.well-known/webfinger
?resource=acct%3Am.mustermann%40funcorp.com
&rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer
HTTP/1.1
Host: funcorp.com

Dabei wird im Parameter resource die E-Mail-Adresse als Identifier des betreffenden Benutzers übergeben. Da es sich bei WebFinger um einen generischen Internet-Dienst für das Bestimmen von Adressen handelt, bekommt der WebFinger-Server mit dem Parameter rel (Relation) mitgeteilt, dass der Client in diesem Fall an der sogenannten Issuer-URL des OpenID Provider der Fun Corp interessiert ist. Diese liefert der Server auch prompt in der entsprechenden HTTP Response:

HTTP/1.1 200 OK
Content-Type: application/jrd+json

{
"subject": "acct:joe@example.com",
"links":
[
{
"rel": "http://openid.net/specs/connect/1.0/issuer",
"href": "https://accounts.funcorp.com"
}
]
}

Die Response verwendet im Falle von WebFinger den Content Type application/jrd+json, wobei "jrd" für "JSON Resource Descriptor" steht. Im Response-Parameter href liefert der Server eine Issuer-URL wie im früheren Artikel. Dabei handelt es sich um die eindeutige ID des OP von Fun Corp, die auch die ID Tokens des betreffenden OP verwenden. OpenID Connect Discovery legt nun fest, dass unter dem Unterpfad /.well-known/openid-configuration eben dieser URL Metadaten über den OP zur Abfrage zur Verfügung zu stellen sind. Also sendet der Client einen entsprechenden Request an diese URL:

GET /.well-known/openid-configuration HTTP/1.1
Host: accounts.funcorp.com

Der Request liefert im Ergebnis ein Dokument mit den gesamten Metadaten des OpenID Providers von Fun Corp:

HTTP/1.1 200 OK
Content-Type: application/json

{
"issuer":
"https://accounts.funcorp.com",
"authorization_endpoint":
"https://accounts.funcorp.com/oauth/auth",
"token_endpoint":
"https://accounts.funcorp.com/oauth/token",
...
"userinfo_endpoint":
"https://accounts.funcorp.com/userinfo",
...
"jwks_uri":
"https://server.example.com/jwks.json",
"registration_endpoint":
"https://accounts.funcorp.com/connect/register",
"scopes_supported":
["openid", "profile", "email", "address",
"phone", "offline_access"],
"response_types_supported":
["code", "code id_token", "id_token", "token id_token"],
...
"display_values_supported":
["page", "popup"]
...
}

Dazu zählen insbesondere die verschiedenen Endpunkte (z. B. der zur Autorisierung im Wert authorization_endpoint), aber auch eine Liste der unterstützten Scope-Werte (scopes_supported/i]) und Response-Typen ([i]response_types). Auf Basis dieser Informationen kann der Client entscheiden, welche Requests er gegen welche URLs absetzen wird, um den Benutzer zu authentifizieren.

Bevor der Authentifizierungsprozess starten kann, benötigt News Corp für die weiteren Interaktionen eine gültige OAuth client_id bei Fun Corp. Da sich beide vorher nicht kannten, ist hierfür ein dynamischer Prozess erforderlich, der bei Bedarf durchgeführt wird. Hierfür spezifiziert OpenID Connect die sogenannte dynamische Client-Registrierung. Kern dieser Spezifikation ist ein weiterer Endpunkt für die Registrierung von Clients (registration_endpoint). An ihn sendet der Client jetzt einen Registrierungs-Request.

POST /connect/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: accounts.funcorp.com

{
"application_type": "web",
"redirect_uris":
["https://portal.newscorp.com/callback"],
"client_name": "News Corp",
"token_endpoint_auth_method": "client_secret_basic",
...
}

Im Request kann der Client dem Autorisierungsserver alle notwendigen Metadaten über sich bekannt geben. Unter anderem kann er seinen Anwendungstyp (application_type) und seine Redirect-URIs spezifizieren. Der Server wird beim Verarbeiten von Authentifizierungs-Requests ausschließlich Redirect-URIs akzeptieren, die hier aufgeführt wurden. Als Ergebnis des Registrierungs-Requests legt der Autorisierungsserver einen neuen Client Account an und liefert in der Response, neben einer Menge weiterer Metadaten, die zugehörige client_id und gegebenenfalls das korrespondierende client_secret an den Client aus.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
"client_id": "s6BhdRkqt3",
"client_secret":
"ZJYCqe3GGRvdrudKyZS0XhGv_Z45DuKhCUk0gBR1vZk",
"client_secret_expires_at": 1577858400,
...
}

Unter Nutzung der neuen client_id kann das Nachrichtenportal jetzt einen Standard-Authentifizierungs-Request an Fun Corp stellen.

HTTP/1.1 302 Found
Location: https://accounts.funcorp.com/oauth/auth?
response_type=code
&scope=openid%20profile%20email
&client_id=s6BhdRkqt3
&state=3479087654367666666765
&redirect_uri=https%3A%2F%2Fportal.newscorp.com%2Fcallback

Der gesamte Prozess des Logins und des Zugriffs auf Benutzerdaten entspricht dem im ersten Artikel vorgestellten Abläufen.

Bei der Bereitstellung von Benutzerdaten an Dritte wird jedoch davon ausgegangen, dass der OpenID Provider die Zustimmung des Benutzers vor dem Übertragen der Daten an den Client einholt (der sogenannte "User Consent"). Des Weiteren erlaubt es OpenID Connect, dass der OP für jeden Client und einen bestimmten Benutzer eine andere Benutzer-ID (einen sogenannten "Pairwise Pseudonymous Identifier") ausstellt. Das soll verhindern, dass verschiedene Clients Daten einem bestimmten Benutzer zuordnen können.

In manchen Situationen möchte die Anwendung gezielt darauf Einfluss nehmen, ob der OP mit dem Benutzer im Rahmen des Authentifizierungsprozesses eine Benutzerinteraktion durchführt und welche Methoden er hierzu verwendet. Dazu stellt OpenID Connect einige Stellschrauben bereit: Mit dem Parameter "prompt" kann der Client steuern, ob eine Benutzerinteraktion stattfindet. Stellvertretend sollen hier zwei (komplementäre) Werte erläutert werden.

Wenn der Client möchte, dass eine Benutzerinteraktion auf keinen Fall stattfindet, zum Beispiel bei der Eingabe von Credentials, verwendet er den Wert "none". Kann der OP unter dieser Bedingung den Prozess nicht erfolgreich durchführen, dann wird als Ergebnis des Authentifizierungsablaufs eine aussagekräftige Fehlermeldung, etwa login_required, an den Client zurückgemeldet. Die Option "none" wird gerne verwendet, um Portale (optional) zu personalisieren, wenn sowieso mit hoher Wahrscheinlichkeit eine Login-Sitzung des Benutzers vorliegt. In einem solchen Fall möchte das Portal aber nicht, dass der Prozess blockiert, weil eine Eingabeseite für Benutzername und Passwort angezeigt wird.

An dieser Stelle sei explizit darauf hingewiesen, dass kein Client diese Option verwenden darf, um unautorisiert auf Identitätsdaten eines Benutzers zuzugreifen. Grundsätzlich sollte der OP solche Daten nur an einen Client weitergeben, wenn dieser hierzu autorisiert ist. Das kann durch eine systemseitige Policy oder durch die explizite Freigabe durch den Benutzer erfolgen. Liegt eine solche Autorisierung nicht vor, wird der OP den Request mit einer Fehler-Response consent_required beantworten.

Mit dem Wert "login" signalisiert der Client an den Autorisierungsserver, dass der Benutzer unmittelbar durch (ggf. erneute) Eingabe von Credentials authentifiziert werden soll – ein SSO darf also nicht greifen. Diese Option kommt zum Beispiel zum Einsatz, wenn der Client eine besonders sicherheitskritische Operation durchführen möchte (z. B. Passwortänderung oder einen Bezahlvorgang) und daher sicherstellen will, dass wirklich der legitime Benutzer gerade das Gerät nutzt und keine Übernahme einer laufenden Sitzung durch einen anderen Benutzer erfolgt ist.

Es kann auch sein, dass der Client nur eine erneute Eingabe der Credentials erzwingen möchte, wenn seit der letzten Authentifizierung schon eine bestimmte Zeit vergangen ist. In dem Fall kann er anstelle von "prompt" den Parameter "max_age" verwenden, in dem er (in Sekunden) spezifiziert, wie lange der Zeitpunkt der Authentifizierung höchstens vergangen sein darf.

Möchte der Client ein bestimmtes Sicherheitsniveau bei der Authentifizierung des Benutzers vorgeben, verwendet er den Parameter "acr_values", um die symbolischen Namen von Authentifizierungs-Policies (sog. "Authentication Context Class Reference") anzugeben, denen die Authentifizierung genügen muss. Welche der angeforderten Policies erfüllt wurde, teilt der OP im "acr"-Claim des ID Token mit. Die Spezifikation legt keine konkreten Policies fest, verweist aber auf den ISO-Standard 29115. In ihm wird die Verlässlichkeit eines Authentifizierungsvorgangs in vier Klassen (Levels of Assurance 1-4) aufgeteilt. Ein möglicher Wert könnte also acr_values="iso29115_3" sein.

Typischerweise sind die Anforderungen an die Qualität der Nutzungserfahrung einer Anwendung hoch. Das Verwenden eines Redirect-basierten Protokolls und eigener HTML-Masken für das Login erschwert dabei einen nahtlosen Fluss durch die Anwendung. Um die Integration dennoch so gut wie möglich implementieren zu können, stellt OpenID Connect durch den Parameter "display" einen Weg bereit, dem OP Hinweise auf die gewünschte Art der Darstellung der Benutzerschnittstelle zu geben. Damit kann der Client dem OP zum Beispiel mitteilen, ob er als volle Browserseite (display=page) oder in einem Pop-up-Fenster (display=popup) dargestellt wird. Diese Information kann der OP verwenden, um seine Darstellung entsprechend anzupassen. Damit erreicht man, dass der verfügbare Raum zielgerichtet verwendet wird beziehungsweise die Eigenschaften der Geräteklasse (display=touch) besonders berücksichtigt werden. Es steht dem OP aber immer frei, die Eigenschaften des User Agent selbstständig zu erkennen und seine Benutzerschnittelle entsprechend zu adaptieren (Responsive Design).

Wünscht der Client die Verwendung einer bestimmten Sprache, die etwa von den Einstellungen des Browsers abweicht, kann er diese mit dem Parameter "ui_locales" anfordern.

Eine perfekte Integration zwischen dem OP und den umgebenden Prozessen erfordert aber noch andere Funktionen. Eine ermöglicht der Parameter "login_hint". Hiermit kann der Client dem OP einen Hinweis geben, mit welcher Benutzer-ID sich der Benutzer einloggen möchte, zum Beispiel einer E-Mail-Adresse oder einem Benutzernamen. Die Verwendung dieses Parameters macht in Situationen Sinn, in denen der Client den Benutzer schon im Vorfeld nach seiner Benutzer-ID gefragt oder diesen anderweitig identifiziert hat. Dann spart sich der Benutzer die erneute Eingabe des Benutzernamens.

In Installationen mit einer hohen Anzahl von Login-Vorgängen kommt der Optimierung des Login-Vorgangs (Dauer und produzierte Last) eine große Bedeutung zu. Hier kann der Parameter "claims" zum Einsatz kommen, um die Anzahl der Requests zu verringern. Er erlaubt es dem Client, gezielt Claims zum Benutzer oder dem Authentifizierungsvorgang dem ID Token oder dem UserInfo-Endpunkt zuzuordnen. Wenn der Client das nutzt, um die essenziell erforderlichen Claims dem ID Token zuzuweisen, dann stehen alle erforderlichen Benutzerdaten sofort nach dem Umtausch des Autorisierungs-Codes zur Verfügung und der Client spart sich (und dem OP) den zusätzlichen Aufruf auf dem UserInfo-Endpunkt.

Unter der Annahme, dass der Mediendienst nur den Namen und die E-Mail-Adresse für die Durchführung des Logins benötigt, könnte der Parameter für das Beispiel wie folgt aussehen:

{
"id_token":
{
"name": {"essential": true},
"email": {"essential": true},
"email_verified"; {"essential": true},
}
}

Der entsprechende Authentifizierungs-Request enthält dann das JSON-Objekt (Form URL-encoded) als Wert des Parameters "claims":

  HTTP/1.1 302 Found
Location: https://accounts.funcorp.com/oauth/auth?
response_type=code
&scope=openid
&client_id=SDFGHJKLUZTREDFGHJ
&state=34790876543456789765
&redirect_uri=https%3A%2F%2Fmediaservice.funcorp.com%2Flogin_cb
&claims=%7B%22id_token%22%3A%0A%20%7B%22name%22%3A%20%20%7B%22essential%22%3A%20true%7D%2C%0A%20%20%22email%22%3A%20%20%7B%22essential%22%3A%20true%7D%2C%0A%20%20%22email_verified%22%3B%20%7B%22essential%22%3A%20true%7D%2C%0A%20%7D%0A%7D%0A

Im Ergebnis würde das ID Token dann die folgenden Daten enthalten:

{
"iss": "https://accounts.funcorp.com",
"sub": "786767677",
"aud": "SDFGHJKLUZTREDFGHJ",
"exp": 1388700360000,
"iat":1388696760000,
"auth_time": 1388696760000,
"name": "Max Mustermann",
"email": "m.mustermann@funcorp.com"
"email_verified": true
}

Alternativ lässt sich das Login mittels "grant type implicit" durchführen, denn hierbei werden alle Daten bereits mit dem Redirect zurück zum Client ausgeliefert. Der Client spart sich damit den Aufruf auf dem Token-Endpunkt. Probleme mit der Länge der Redirect-URL sollten dabei nicht auftreten, da der Server die ID-Daten in einem sogenannten Fragment nur zum User Agent überträgt. Dadurch wird die Implementierung aber auch schwieriger, denn das Frontend der Anwendung muss gegebenenfalls dafür sorgen, dass Access- und ID Token zum Backend übertragen werden. Hierzu ist im Frontend der Anwendung JavaScript und im Backend eine passende Schnittstelle erforderlich. Hinzu kommt, dass die Integrität und Authentizität des ID Token über eine digitale Signatur sicherzustellen ist. Des Weiteren muss man berücksichtigen, dass der Implicit Grant nicht geeignet ist, um Refresh Tokens auszustellen.

Letztlich ist die Wahl des "richtigen" Grant Type abhängig vom Verhältnis der Bandbreite zwischen User Agent und Relying Party (RP) beziehungsweise OP auf der einen Seite (implicit) und der Bandbreite zwischen RP und OP auf der anderen Seite (Code). Das bedeutet, bei langsamen Internet auf dem mobilen Endgerät ist der Grant Types Code besser geeignet, da hier die Daten direkt zwischen RP und OP übertragen werden. Auf dieser Strecke sollte in der Regel eine hohe Bandbreite verfügbar sein. Ein Vorzug von OpenID Connect ist, dass die Anwendung überhaupt eine Wahl hat, wie sich der Login-Prozess optimal implementieren lässt.

Und was ist nun mit den eingangs erwähnten kombinierten Szenarien, in denen der Client nicht nur Identitätsdaten benötigt, sondern auch im Namen des Benutzers auf andere Ressourcen zugreifen möchte? Solche Anwendungen machen für Multi-Service-Anbieter wie Google oder die Deutsche Telekom Sinn. Im Beispiel könnte man sich vorstellen, dass der Mediendienst im Namen des Benutzers auch auf dessen Adressbuch beim E-Mail-Dienst von Fun Corp zugreifen möchte, um Einladungen für Shares versenden zu können. Umgekehrt ist es denkbar, dass der E-Mail-Service den Mediendienst verwendet, um Anhänge abzulegen oder von dort Dateien zu laden.

Ist der OpenID Provider auch der OAuth-Autorisierungsserver des Anbieters, sollte ein Client mit dessen Access Tokens außerdem auf andere Ressourcenserver zugreifen können. Bezüglich der Nutzbarkeit eines konkreten Access Token bei unterschiedlichen Diensten gibt es leider – bedingt durch unterschiedliche Token-Designs und Security Policies – essenzielle Unterschiede zwischen den Implementierungen der Anbieter. Bei Google etwa kann der Client ein Access Token für alle freigeschalteten Dienste eines Clients verwenden. Andere Dienstanbieter wie die Deutsche Telekom stellen aus Sicherheitsgründen verschiedene Access Tokens für unterschiedliche Ressourcenserver aus. Das soll verhindern, dass sich bei einem Einbruch bei einem konkreten Dienst abgefangene Access Tokens für unautorisierte Zugriffe auf andere Dienste missbrauchen lassen. Diese Vorgehensweise hat natürlich Auswirkungen auf das Token-Handling des Clients.

Auf das Beispiel angewendet bedeutet das,dass sich ein Access Token für den UserInfo-Endpunkt gegebenenfalls nicht für den Zugriff auf den Adressbuchdienst verwenden lässt. Dem Client stehen dann zwei Optionen zur Auswahl: Er kann weitere Access Tokens durch ein erneutes Durchlaufen des OAuth Browser-Flows erlangen. Die bessere Nutzungserfahrung wird aber erreicht, wenn der Autorisierungsserver dem Client initial ein Refresh Token ausstellt, dass dieser danach zum Abfragen weiterer dienstspezifischer Access Tokens verwenden kann. Diese von Justin Richer, Principal Technologist bei MITRE, als "Über Refresh Token" bezeichnete Vorgehensweise soll am Beispiel skizziert werden. Der Client fordert mit dem initialen Authentifizierungs- und Autorisierungs-Request sowohl OpenID Connect als auch Zugriff auf den Adressbuchdienst an.

HTTP/1.1 302 Found
Location: https://accounts.funcorp.com/oauth/auth?
response_type=code
&scope=openid%20contacts
&client_id=SDFGHJKLUZTREDFGHJ
&state=300965456343676767
&redirect_uri=https%3A%2F%2Fmediaservice.funcorp.com%2Flogin_cb

Im Beispiel entscheidet der Autorisierungsserver, das initiale Access Token für den UserInfo-Endpunkt auszustellen, und teilt das dem Client im Response-Parameter "scope" mit.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
"access_token": "4vfKjkM8FcGvnzZUN4_KSP0aAp",
"scope": "userinfo",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhb...cifQ.ew...fQ.gg...zqg",
"refresh_token": "67676q6876r8978rq7"
}

Des Weiteren stellt der Autorisierungsserver ein Refresh Token aus, dass der Client beim Anfordern weiterer Access Tokens für den betreffenden Benutzer verwenden kann. Hierzu nutzt der Client den Grant Type refresh_token wie folgt:

POST /oauth/token HTTP/1.1
Host: accounts.funcorp.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic U0RGR0hKS0xVWlRSRURGR0hKOnRlc3QxMjM0

grant_type=refresh_token&
refresh_token=67676q6876r8978rq7&
scope="contacts"

Nun ist der Client im Besitz von Access Tokens für beide relevanten Dienste.

Mehr Infos

Und so weiter ...

Man könnte noch viele weitere Anwendungsfälle vorstellen, die OpenID Connect adressiert. Dem interessierten Leser sei dafür das Studium der Kernspezifikationen und die ergänzende Spezifikation zur Sitzungsverwaltung und zum Log-out ans Herz gelegt:

OpenID Connect ist ein zeitgemäßes Login-Protokoll für alle relevanten Anwendungsfälle. Das ambitionierte Ziel der OpenID Foundation ist es, mit dem neuen Protokoll sowohl OpenID 2.0 als auch SAML 2.0 zu ersetzen. Daher ist es funktional gesehen wesentlich mächtiger als OpenID 2.0 und soll einfache Social Log-ins, aber auch wesentlich kritischere Abläufe in den Bereichen E-Health und E-Government unterstützen. Die Devise bei seiner Entwicklung war: "Einfache Dinge sollten einfach sein und komplizierte Dinge sollten möglich sein." Entsprechend bietet OpenID Connect einen einfachen Einstieg in das Thema. In den meisten hier gezeigten Anwendungsfällen kommt der Client zum Beispiel mit ein paar einfachen HTTP Requests ohne irgendwelche Kryptographie aus.

Gleichzeitig ist aber auch die Unterstützung von Szenarien mit hohen Sicherheitsanforderungen, wie sie im Bereich E-Health verständlicherweise erforderlich sind, möglich. Hierzu gibt es ein umfangreiches Repertoire an Funktionen, wie die erzwungene Authentifizierung, digital signierte Log-in-Requests und ID Tokens. Dass OpenID Connect auf den Erfahrungen von OpenID 2.0 und SAML aufbaut, merkt man der Spezifikation an. Nach den Erfahrungen des Autors findet man in der Spezifikation überraschend oft einfache Möglichkeiten für die Lösung auch anspruchsvoller praktischer Anwendungsfälle. Bei der Deutschen Telekom ist OpenID Connect daher seit Ende 2013 das Standardprotokoll für die Integration von Telekom- und Partneranwendungen in das "Telekom Login".

Der Erfolg von OpenID Connect lässt sich auch am aktuellen Implementierungsstand ermessen. Es existieren kurz nach der offiziellen Verabschiedung bereits eine Vielzahl unterschiedlicher Implementierungen in diversen Bereichen, von experimentellen Umsetzungen über die Identity-Provider von Internetdiensten bis hin zu Modulen von Standardsoftware für Unternehmen. Eine große Anzahl dieser Implementierungen nehmen am Interoperabilitätstest der OpenID Foundation teil.

Dr. Torsten Lodderstedt
verantwortet bei der Deutschen Telekom als Abteilungsleiter die Entwicklung von Basisdiensten für das Identitäts- und Vertrags-Management sowie Bezahlfunktionen, die in diversen Endkundenprodukten zum Einsatz kommen. Er ist Corporate Director der OpenID Foundation und an der Spezifikation von OpenID Connect und OAuth beteiligt.
(ane)