
Vor kurzem musste ich die Unterstützung für die anonyme Benutzerauthentifizierung basierend auf OpenId Connect und OAuth 2.0 auf der ASP.NET Core-Plattform implementieren. Die Spezifikation dieser Protokolle wird hier nicht erläutert, dazu gibt es vollständige Artikel zum Habr. Kommen wir zum Punkt.
Warum brauchen wir ein anonymes Token? Um einen anonymen Benutzer für eine API-Ressource zu autorisieren, insbesondere in der Architektur von Microservices, kann er außerdem den Status unserer Anwendung ändern. Vasya mochte beispielsweise ein T-Shirt mit Katzen, legt es in den Warenkorb des Online-Shops und gibt möglicherweise eine Bestellung als Gast auf. Um zu verstehen, dass es sich um Vasily handelte, enthält das anonyme Token die Kennung des anonymen Benutzers und die Sitzungskennung. Wenn sich Vasily anmeldet, werden diese Parameter in das authentifizierte Token aufgenommen.
Darüber hinaus kann ein anonymes Zugriffstoken zusätzliche Aussagen (oder Ansprüche) enthalten.
Die Werkzeuge
Implementierung
IdentityServer4 hat viele Beispiele auf GitHub.
Das Hinzufügen von Unterstützung für anonyme Token ist ganz einfach:
Interaktionsszenario
Erwägen Sie, ein anonymes Token für den impliziten Fluss und den Autorisierungscode-Fluss zu erhalten .
Autorisierungspunktanforderung
Um der Spezifikation zu folgen, lautet eine Anforderung für einen Autorisierungspunkt für Implicit Flow wie folgt.
GET /connect/authorize? client_id=client1& scope=openid email api1& response_type=id_token token& redirect_uri=https://myapp/callback& state=abc& nonce=xyz& acr_values=0& response_mode=json
Für den Authorization Code Flow eine ähnliche Anforderung mit response_type = code (PKCE ist optional).
Die Unterschiede zwischen einer regulären und einer anonymen Anfrage in zwei Parametern:
- Der Parameter acr_values = 0 signalisiert eine anonyme Anmeldung. Bei Interesse können Sie die OpenId Connect- Spezifikation lesen.
- Der Parameter response_mode = json wird verwendet, um in Form von Json ohne unnötige Weiterleitungen zu antworten.
Token empfangen
Abhängig vom Authentifizierungsstatus wird entweder ein anonymes oder ein authentifiziertes Token zurückgegeben.
Impliziter Fluss
In diesem Fall antwortet der Autorisierungspunkt in Form von Json, einschließlich des Zugriffstokens.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1", "state": "abc", "session_state": <optional> }
Ablauf des Autorisierungscodes
Bei diesem Ansatz antwortet der Autorisierungspunkt in Form von Json, einschließlich des Autorisierungscodes.
{ "code": <authorization_code>, "scope": "openid email api1", "state": "abc", "session_state": <optional> }
Anschließend müssen Sie den Code mithilfe der Standardmethode gegen das Token austauschen.
Wir bilden eine Anfrage an den Endpunkt des Tokens.
POST /connect/token client_id=client2& client_secret=secret& grant_type=authorization_code& code=`& redirect_uri=https://myapp/callback
Infolgedessen antwortet der Token-Endpunkt in Form von Json, einschließlich des Zugriffstokens.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1" }
Vergleich von anonymen und authentifizierten Token
Wenn der Autorisierungsserver keine Authentifizierungsdaten enthält, erhalten wir ein anonymes Token.
{ "nbf": 1566849147, "exp": 1569441147, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "abda9006-5991-4c90-a88c-c96764027347", "auth_time": 1566849147, "idp": "local", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "anon" ] }
Mithilfe der Authentifizierungsmethode (amr) können Sie feststellen, dass der Benutzer anonym ist.
Die Kennung der "allgemeinen" Sitzung (ssid) und die Kennung des Betreffs (sub) werden bei der nachfolgenden Benutzeranmeldung in das authentifizierte Token aufgenommen.
Falls sich der Benutzer angemeldet hat, erhalten wir ein authentifiziertes Token.
{ "nbf": 1566850295, "exp": 1566853895, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "bob", "auth_time": 1566850295, "idp": "local", "aid": "abda9006-5991-4c90-a88c-c96764027347", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "pwd" ] }
Wie Sie sehen können, stimmt die anonyme Benutzer-ID (Hilfe) genau wie ssid mit dem Sub des anonymen Tokens überein. Wenn der Client keine anonyme Anmeldung initiiert hat, enthält das authentifizierte Token nur ssid.
Auf diese Weise können wir einen anonymen Benutzer autorisieren und seine Aktionen nach dem Betreten des Systems identifizieren.
Fazit
In diesem Artikel haben wir ein Szenario zum Abrufen eines anonymen / authentifizierten Tokens mithilfe von IdentityServer4 mit der Erweiterung AnonymousIdentity untersucht .
Wenn Sie Fragen haben, beantworte ich diese gerne in den Kommentaren.