|
|
OAuth / OpenID Connect als Zentraler Anmeldedienst HIT/ZIDStand Juni 2020
Kurz und bündigBevor eine OAuth-Anfrage durchgeführt werden kann, müssen die Clients bei der Zentralen Datenbank registriert worden sein. Jeder Client (nicht der Benutzer!) wird durch seine Kennung, seine Antwort-URIs und ein Passwort authentifiziert. Dann kann damit nach dem OpenID Connect-Verfahren (kurz OIDC) zunächst eine Nutzerautorisierung und schließlich ein Access Token angefordert werden:
Neben diesen kann über OIDC Discovery in Erfahrung gebracht werden, welche URIs und Parameter die OIDC-Schnittstelle versteht: für Test-System. Es ist neben OIDC Core lediglich OIDC Session Management implemeniert. Keines der beiden Channel Logout-Mechanismen sind vorhanden. DetailsRegistrierung ClientNur registrierte Clients können sich mit OAuth verbinden. Da wir (derzeit) eine Client-Registrierung weder per Webseite, noch per HIT-Protokoll, noch per OpenID Connect Dynamic Registration unterstützen, bitte formlos eine Email an helmut.hartmann@hi-tier.de mit folgenden Angaben senden (einfach Tabelle kopieren, in Email einfügen und dort die gelben Felder ausfüllen):
Falls bestimmte Angaben zu eng gefasst sind, wie z.B. zu kurze
Token-Lebensdauern, können wir das ggf. noch anpassen. Uns fehlen da
noch die Erfahrungen. Wir tragen die Angaben manuell bei uns ein und Sie erhalten dann von uns
einen zufällig generierten String, der als Ablauf![]() Die OAuth-Autorisierung nach OIDC läuft in zwei Stufen ab:
Dadurch, dass der Authorization Code eingetauscht wird, ist sichergestellt, dass mögliche PIN-Angaben im Browser (in Schritt 2) dort verbleiben und der Client in Schritt 3 (und folgenden) keine Angaben zur Nutzer-PIN besitzt. Es wird ein klassisches Session-Cookie mitgeführt, um mehrfache Authentifizierungen innerhalb kurzer Zeit zu ermöglichen, ohne sich jedesmal erneut anmelden zu müssen. Erkennt der ZAD ein erhaltenes Session-Cookie, wird sofort ein neuer Authorization Code an den Client zurückgesendet, ohne die Anmeldemaske des ZAD anzuzeigen. Ein explizites Abmelden des Anwenders ist daher auch implementiert, Details dazu siehe unten. In den folgenden Stufen wird die URI für unser Testsystem angegeben. Für die anderen Systeme lautet die URI wie folgt:
Stufe 1: Authorization Code [AUC]Client-Anfrage an den HIT/ZID-Anmeldedienst mit HTTP GETDie URI für die Client-Anfrage (Schritt 1) ist Der Die Angaben für Die Der Optional: Technisch gesehen wird z.B. aus einer Webanwendung heraus ein Redirect an unseren Autorisierungsendpunkt (Schritt 1) abgesetzt: HTTP/1.1 302 Found Location: /HitTest3/zad_oauth/auth_req? scope=openid &response_type=code &client_id=45678R &redirect_uri=https%3A%2F%2Fwww.ihr-client.de%2Froute%2Fendpunkt &nonce=client.session.id &state=xsrf.blocker Host: www.hi-tier.de ( Überprüfung der QueryString-ParameterUnser Endpunkt überprüft auf Vorhandensein der übergebenen Parameter. Wenn nicht ausreichend, dann wird eine entsprechende JSON-Fehlerantwort gesendet. OIDC erlaubt weitere Angaben im Authentication Request, von
denen manche (z.B. Zuerst wird die Client-Angabe Wenn Client gültig, dann wird Wenn Client und Redirect-URI gültig, dann wird zusammen mit einem internen Token zur Anmeldemaske des Zentralen Anmeldedienstes weitergeleitet, auf der sich der Nutzer des Clients als HIT/ZID-Anwender authentifizieren muss (Schritt 2). Schlägt die Anmeldung fehl, kann der Anwender die Anmeldung wie bei
der klassischen HIT-Webanwendung wiederholen, bis er angemeldet ist
(weiterhin Schritt 2).
Kann er sich aufgrund einer falschen PIN nicht anmelden oder ist er
gesperrt, muss er über den Knopf "Abbrechen" zu OAuth zurückkehren. In
dem Fall wird eine entsprechende JSON-Fehlerantwort gesendet (Schritt 3). Beispiel Fehlerantwort, wenn Client nicht autorisiert (Schritt 3): HTTP/1.1 400 Bad Request Content-Type: application/json; charset=utf-8 Cache-Control: private Pragma: no-cache { "error": "invalid_request", "error_description": "OAuth-Anmeldung fehlgeschlagen - CLIENT_ID nicht gefunden", "nonce": "client.session.id", "state": "xsrf.blocker" } Erfolgreiche Anmeldung am HIT/ZID-AnmeldedienstNach erfolgreicher Anmeldung erzeugt der HitServer auf der selben Datenbankverbindung den Authorization Code für diesen Client und dessen Nutzer. Die Antwort-URI wird anhand Beispiel Fehlerantwort, wenn Client autorisiert, aber Nutzeranmeldung abgebrochen (Schritt 3): es wird ein Redirect an den von Ihnen registrierten Endpunkt veranlasst: https://www.ihr-client.de/route/endpunkt? error=unauthorized_client &error_description=Anmeldung+fehlgeschlagen:+Falsche+oder+fehlende+PIN &error_hit=224 &nonce=client.session.id &state=xsrf.blocker Im Schlüssel Beispiel Antwort nach erfolgreicher Anmeldung des Nutzers (Schritt 3): es wird ein Redirect an den von Ihnen registrierten Endpunkt veranlasst: HTTP/1.1 302 Found Location: https://www.ihr-client.de/route/endpunkt?code=ich.bin.der.lange.kurzlebige.auth.code&nonce=client.session.id&state=xsrf.blocker An keiner Stelle wird die PIN des Nutzers aus der Anmeldemaske des Zentralen Anmeldedienstes an den Client übermittelt. Da aber der Authorization Code und die PIN über HTTP-Client oder Webbrowser tranferiert wurden, muss dieser im nächsten Schritt ohne diese Clients durch einen Access Token ersetzt werden.
Stufe 2: Access Token [ACT]Client-Anfrage an den HIT/ZID-Anmeldedienst mit HTTP
|
![]() | entweder einen HTTP-Header Authorization mit dem
Schema Basic und Base64-encodetem
client_id:client_secret
mitsenden |
![]() | oder client_id und client_secret als
Teil des querystring mitliefern |
Letzteres ist laut OAuth zulässig, wenn die Verbindung mit TLS verschlüsselt ist, was sie bei HIT/ZID grundsätzlich ist.
Eine POST-Anfrage mit Authorization
-Header (Schritt 4) sähe so aus:
POST /HitTest3/zad_oauth/token HTTP 1.1 Host: www.hi-tier.de Content-Type: application/x-www-form-urlencoded Authorization: Basic base64base64base64base64base64 grant_type=authorization_code &code=ich.bin.der.lange.kurzlebige.auth.code &redirect_uri=https%3A%2F%2Fwww.ihr-client.de%2Froute%2Fendpunkt
Die Angaben der Autorisierung werden geprüft. Im Fehlerfall wird eine entsprechende JSON-Fehlerantwort gesendet (Schritt 5).
Der Parameter grant_type
muss authorization_code
lauten. Falls nicht, wird eine entsprechende JSON-Fehlerantwort
gesendet (Schritt 5).
Wenn soweit korrekt, werden sämtliche Angaben gegen den HitServer geprüft. Bei fehlerhaften Angaben erhält man eine entsprechende JSON-Fehlerantwort (Schritt 5).
Eine Fehlerantwort bei falscher Client-ID (Schritt 5) sähe z.B. so aus:
HTTP/1.1 400 Bad Request Content-Type: application/json; charset=utf-8 Cache-Control: private Pragma: no-cache { "error": "invalid_client", "error_description": "Falsche Client-Credentials" }
Wenn erfolgreich, liefert der HitServer das Access Token ACT, optional das Refresh Token (RET), und für den Payload in Form eines ID-Token die Betriebsnummer und Mitbenutzerkennung.
Aus diesen Angaben wird eine Datenstruktur (=Payload) für ein
ID-Token befüllt und als
JWT codiert,
dieses als
id_token
zusammen mit dem access_token
, ggf. dem
refresh_token
und weiteren
Angaben
als JSON-Antwort an den Client zurückgesendet (Schritt 5).
Der Client erhält im ID-Token zusätzlich zu den vorgegebenen
Schlüsseln lediglich bnr
und mbn
, da aus
Sicherheitsgründen gegenüber dem HitServer mit einer sehr beschränkten
Kompetenz auf der HIT-Datenbank gearbeitet wird. Möchte man mehr Daten
zum Betrieb erhalten, dann kann dies unter Zuhilfenahme des Access
Token z.B. über unsere REST-Schnittstelle abgefragt werden.
Eine erfolgreiche Antwort auf die Anforderung eines Access Tokens sieht so aus:
HTTP/1.1 200 OK Cache-Control: private Pragma: no-cache Content-Type: application/json; charset=utf-8 { "token_type": "Bearer", "access_token": "mit.mir.kann.man.sich.bei.HIT.autorisieren", "expires_in": 1200, "expires_at": 1576760000, "refresh_token": "wenn.ACT.abgelaufen.nimm.mich", "id_token": "eyJhbGciOiJub25lIn0=.codiertesJWT." }
Die Angabe expires_at
(=Anzahl Sekunden seit Unix Epoch
am 01.01.1970 0 Uhr UTC) ist die einzige ausserhalb der
OIDC-Spezifikation, korreliert aber direkt mit expires_in
:
es ist der Zeitpunkt, an dem das ACT abgelaufen sein wird.
Der Inhalt von Feld access_token
kann nun für die Dauer
von expires_in
Sekunden als Identifikation, als PIN-Ersatz oder als Session-Key verwendet werden.
Als Identifikation genügt der bloße "Besitz" dieses Tokens - damit lässt sich ein Benutzer eindeutig identifizieren.
Darüber hinaus kann das Token -derzeit nur im Test!- in
Kombination mit Betriebsnummer und Mitbenutzerkennung zur Anmeldung
verwendet werden.
Beispiel: Login mit Access Token statt PIN
*1:XS:LOGON/BNR15;MELD_WG;TIMEOUT;OI_C_ID;OI_TOKEN:09 000 000 0001;3;1200;45678R;mit.mir.kann.man.sich.bei.HIT.autorisieren
Die Angabe des Clients OI_C_ID
ist hierbei zusätzlich
erforderlich, um alle von diesem Client zur Betriebsnummer vergebenen
Access Token
zu löschen, falls jemand mehrmals durch
Ausprobieren dieses Token "erraten" möchte. Damit wird verhindert, dass
der Betrieb für die PIN-Anmeldung gesperrt wird.
Im REST-Interface von HIT3 gibt des optional die Parameter cid
(für die Client ID) und act
(für das Access Token), die
statt der Angabe einer Nutzer-PIN verwendet werden können. Auf die
Angabe des act
kann verzichtet werden, wenn das Token als
HTTP-Header Authorization
und dem Schema Bearer
(und nicht als klassisches Basic
-Schema) mitgesendet wird.
Die Clients, die bei der Registrierung (siehe oben) angegeben
haben, dass sie ein refresh_token
nutzen wollen, erhalten dieses
auch in Stufe 2 zusammen mit dem Access Token geliefert.
Das Refresh Token dient dazu, ein abgelaufenes oder auch noch gültiges Access Token zu erneuern.
POST
Die URI für die Client-Anfrage (Schritt 4) ist https://www.hi-tier.de/HitTest3/zad_oauth/token
Da eine HTTP POST
-Anfrage zwingend ist, enthält der
HTTP-Content (nicht die URI) dieser Anfrage einen
querystring
,
der aus grant_type=refresh_token&refresh_token=XXX&scope=openid
besteht.
Der Content-Type
dafür ist application/x-www-form-urlencoded
.
Der HTTP POST
-Request muss autorisiert sein, d.h.
![]() | entweder einen HTTP-Header Authorization mit dem
Schema Basic und Base64-encodetem
client_id:client_secret
mitsenden |
![]() | oder client_id und client_secret als
Teil des querystring mitliefern |
Letzteres ist laut OAuth zulässig, wenn die Verbindung mit TLS verschlüsselt ist, was sie bei HIT/ZID grundsätzlich ist.
Eine POST-Anfrage mit Authorization
-Header (Schritt 4) sähe so aus:
POST /HitTest3/zad_oauth/token HTTP 1.1 Host: www.hi-tier.de Content-Type: application/x-www-form-urlencoded Authorization: Basic base64base64base64base64base64 grant_type=refresh_token &scope=openid &refresh_token=wenn.ACT.abgelaufen.nimm.mich
Die Angaben der Autorisierung werden geprüft. Im Fehlerfall wird eine entsprechende JSON-Fehlerantwort gesendet (Schritt 5).
Der Parameter grant_type
muss refresh_token
lauten, auch scope
ist vorgegeben. Falls nicht, wird eine
entsprechende JSON-Fehlerantwort gesendet (Schritt 5).
Wenn soweit korrekt, werden sämtliche Angaben gegen den HitServer geprüft. Bei fehlerhaften Angaben erhält man eine entsprechende JSON-Fehlerantwort (Schritt 5). Auch, wenn das Refesh Token selbst bereits abgelaufen ist.
Wenn erfolgreich, wird mit dem neuen Access Token (das bisherige wird gelöscht, wenn noch gültig)
eine Antwort gebildet.
Weitere Angaben für z.B. ein neues ID-Token werden nicht
ermittelt (also kein "frisches" Payload).
Eine Fehlerantwort bei falscher Client-ID (Schritt 5) sähe so aus:
HTTP/1.1 400 Bad Request Content-Type: application/json; charset=utf-8 Cache-Control: private Pragma: no-cache { "error": "invalid_client", "error_description": "Falsche Client-Credentials" }
Eine einfache JSON-Antwort mit dem neuen Access Token, dem bekannten Refresh Token und dessen Gültigkeitsdauer wird erzeugt und geliefert (Schritt 5).
Beispiel:
HTTP/1.1 200 OK Cache-Control: private Pragma: no-cache Content-Type: application/json; charset=utf-8 { "token_type": "Bearer", "access_token": "ich.bin.ab.jetzt.zustaendig.fuer.HIT", "expires_in": 1200, "expires_at": 1576777777, "refresh_token": "wenn.ACT.abgelaufen.nimm.mich" }
Nach erfolgreicher Anmeldung in der Anmeldemaske des Zentralen Anmeldedienstes wird ein klassisches Session-Cookie gesetzt, das einen Nutzer für die nächsten 20 Minuten authentifiziert. Nach einem erfolgreichen Austausch des Authorization Code in ein Access Token ändert sich diese Laufzeit auf die bei der Registrierung des Clients gewünschte Laufzeit des Access Tokens.
Wird in der Zeit, in der die Session besteht, ein neuer Authorization Request
versendet, erhält man einen neuen Authorization Code, ohne sich neu anmelden zu müssen.
Damit diese Session vorzeitig beendet werden kann, z.B. wenn die Sitzung nicht
mehr benötigt wird oder ein anderer Nutzer sich anmelden möchte, gibt es den
end_session_endpoint mit der URI: https://www.hi-tier.de/HitTest3/zad_oauth/let_me_go
Die URI besitzt drei Parameter, keiner davon ist zwingend:
![]() | id_token_hint : das erhaltende ID-Token kann als
Hinweisgeber für eine Sitzung mitgesendet werden, um inbesondere nach Ablauf
der Session dennoch geordnet per Redirect zurückkehren zu können |
![]() | post_logout_redirect_uri : dies ist das gewünschte Ziel zum
Rückkehren per Redirect. Dieses muss angegeben werden, wenn bei der
Registrierung mehr als nur ein Rückkehrziel angegeben wurde! |
![]() | state : ein für den Client zum Schutz vor XSRF interessanter
Status, der durchgeschleift wird. Sollte state nicht zum Client
gehören, weil ein Dritter den Logout durchführt, findet der Logout dennoch
statt. |
Weder das OpenID Connect Front-Channel Logout noch das OpenID Connect Back-Channel Logout sind hier implementiert!
Stimmen Parameter nicht oder passt das ID-Token nicht zur Session oder kann die Weiterleitungs-URI nicht eindeutig bestimmt werden, erhält man eine JSON-Antwort als Fehlermeldung.
..
![]()
© 1999-2019 Bay.StMELF,
verantwortlich für die Durchführung sind die
Stellen der Länder ,
fachliche Leitung ZDB: Frau Dr. Kaja.Kokott@hi-tier.de,
Technik: Helmut.Hartmann@hi-tier.de
Seite zuletzt bearbeitet:
05. August 2019 12:58,
Anbieterinformation: Impressum und Datenschutz.
|