Wie gestaltet man einen Authentifizierungsflow?

Raphael_

Aktives Mitglied
Hallo,

ich arbeite derzeit an der Entwicklung einer Website, die ein Frontend und ein Backend umfasst. Die Website soll es Benutzern ermöglichen, Konten zu erstellen, um persönliche Informationen zu speichern. Für das Authentifizierungs- und Autorisierungsverfahren habe ich Keycloak als Lösung gewählt. Keycloak verwaltet die Benutzer, sodass ich nicht alles von Grund auf neu entwickeln muss. Diese Lösung basiert auf JWT (JSON Web Tokens).

Nun habe ich folgende Frage: Wenn Benutzer Daten über sich selbst speichern sollen, benötige ich eine Datenbank (die Auswahl der Datenbank ist noch nicht final). Wie gehe ich am besten vor, wenn sich ein neuer Benutzer registriert? Wenn sich jemand in Keycloak registriert, müsste ich in meiner Datenbank eigentlich eine eindeutige Benutzer-ID generieren, um den Benutzer später identifizieren zu können.

Meine Idee war, eine ID basierend auf dem "sub"-Wert zu generieren, der Teil des JWTs ist, indem ich ein Hash-Verfahren verwende. Diese generierte "ID" würde ich dann in meiner Datenbank speichern. Auf diese Weise könnte ich bei der Anmeldung eines Benutzers einfach den "sub"-Wert extrahieren und mithilfe des Hash-Verfahrens die zugehörige ID in meiner Datenbank abrufen.

Da ich in diesem Bereich noch keine Erfahrung habe, bin ich mir unsicher, ob meine Idee sinnvoll ist. Deshalb frage ich nach bewährten Methoden und wie so etwas normalerweise umgesetzt wird.

Vielen Dank im Voraus! :)
 

KonradN

Super-Moderator
Mitarbeiter
Deine Idee ist schon richtig und genau das solltest Du machen.

Wenn Du einen Request mit JWT bekommst, dann wertest Du das JWT aus. Im sub Feld hast Du die eindeutige ID des Users und dann kannst Du schauen, ob es den User schon gibt oder nicht. Und dann kannst Du ggf. den User anlegen wenn er noch nicht existiert.

(Das wäre die Idee, wenn KeyCloak der Master ist und alle User entsprechend berechtigt sind!)

Ggf. bekommst Du auch noch weitere Informationen wie Email Adresse, Name, .... In so einem Fall kann es Sinn machen, auch diese Werte zu prüfen und ggf. bei Dir zu ändern (So Du die Werte auch gespeichert hast. Evtl. ist das aber unnötig, da Du nichts redundant speicherst.)

Aber da ist kein Hashing notwendig. Die Id des Users würde ich direkt speichern.
 

Raphael_

Aktives Mitglied
Deine Idee ist schon richtig und genau das solltest Du machen.

Wenn Du einen Request mit JWT bekommst, dann wertest Du das JWT aus. Im sub Feld hast Du die eindeutige ID des Users und dann kannst Du schauen, ob es den User schon gibt oder nicht. Und dann kannst Du ggf. den User anlegen wenn er noch nicht existiert.

(Das wäre die Idee, wenn KeyCloak der Master ist und alle User entsprechend berechtigt sind!)

Ggf. bekommst Du auch noch weitere Informationen wie Email Adresse, Name, .... In so einem Fall kann es Sinn machen, auch diese Werte zu prüfen und ggf. bei Dir zu ändern (So Du die Werte auch gespeichert hast. Evtl. ist das aber unnötig, da Du nichts redundant speicherst.)

Aber da ist kein Hashing notwendig. Die Id des Users würde ich direkt speichern.
Danke erstmal für deine Antwort.

Mir kamen jetzt 2 Fragen.

1. Das bedeutet, dass der Datenflow dann so ist, dass jemand im Frontend was eingibt, diese Infos dann ans Backend gesendet werden und das Backend dann die Informationen an Keycloak sendet, um die Registrierung durchführt, ist das richtig? Weil wenn ich das mit der id speichern nicht machen müsste, dann könnte ich ja direkt vom Frontend die Anmeldedaten ans Keycloak senden, oder?

2. Was mache ich, wenn sich ein Nutzer registriert, meine Datenbank aber aus irgendwelchen Gründen nicht erreichbar ist? In diesem Fall hätte Keycloak ja einen Nutzer registriert aber ich könnte die id nicht in der Datenbank speichern.

Danke für deine Hilfe!
 

KonradN

Super-Moderator
Mitarbeiter
Nein, Der Ablauf sieht anders aus.

Der Nutzer greift auf das Frontend zu. Wenn er nicht angemeldet ist, dann ist kein Token vorhanden.
Nun will der Nutzer sich anmelden. Das macht Keycloak, d.h. der Webbrowser wechselt zu einer Seite von Keycloak.
Dort meldet der Nutzer sich an. Wenn er angemeldet ist, erzeugt Keycloak ein Token und leitet dann den Browser an eine URL weiter (Diese ist entweder fest konfiguriert oder diese wurde im Request, die den Login angefordert hat, mitgegeben. In der Regel ist es so, dass ein Pattern verpflichtend ist, also es muss myapp.com als Domain sein. Aber der Login kann von vielen Seiten kommen, die public sind und am Ende möchte an ja wieder auf der Seite sein - nur eben angemeldet)
Bei der Weiterleitung ist im Browser aber nun das Token mit hinterlegt. Das kann das Frontend nun auswerten und erhält dadurch dann gewisse Informationen wie Name, Email Adresse und all sowas....

Wenn das Frontend auf das Backend zugreift, dann wird dieses Token vom Nutzer einfach mitgegeben.

Für die Nutzerdaten selbst ist Keycloak verantwortlich. Das kannst Du soweit konfigurieren. Du kannst also für Login und so eigene Seiten hinterlegen, damit es so aussieht, wie Du willst. Und Du kannst in Keycloak für ein Realm "Enable User Registration" aktivieren.

Wichtig ist, dass die Verantwortung wirklich bei Keycloak liegt. Du solltest da also keine Vertraulichen Informationen in Deiner App verwalten oder pflegen. Du bekommst also nie das Passwort zu sehen. Der User muss sich auch nicht mit Passwort anmelden. Evtl. meldet er sich mit einem Zertifikat an oder mit irgend etwas anderem... Evtl. mit einem anderen Identity Provider wie Microsoft, Google, Facebook, Github, ....

Das ist nicht die Verantwortung Deiner App. Das ist der Verantwortungsbereich von Keycloak. Und das kann man da alles konfigurieren.
Deine Anwendung (Frontend wie Backend) vertrauen der Keycloak Instanz und damit dem Token.
 

KonradN

Super-Moderator
Mitarbeiter
Ach ja - wenn eine Ressource nicht da ist (z.B. eine Datenbank) - dann funktioniert alles natürlich nicht. Das ist aber doch etwas ganz normales. Wenn die Datenbank Deiner App nicht funktioniert, dann funktioniert das Backend nicht und da das Frontend das Backend braucht, wird das auch nicht gehen. Bei irgendwelchen Anfragen wird dann vermutlich im Backend eine Exception kommen was dann zu einem 5xx http Status Code führen dürfte. Und das wird dann im Frontend hoffentlich irgendwie angezeigt.
 

Raphael_

Aktives Mitglied
Nein, Der Ablauf sieht anders aus.

Der Nutzer greift auf das Frontend zu. Wenn er nicht angemeldet ist, dann ist kein Token vorhanden.
Nun will der Nutzer sich anmelden. Das macht Keycloak, d.h. der Webbrowser wechselt zu einer Seite von Keycloak.
Dort meldet der Nutzer sich an. Wenn er angemeldet ist, erzeugt Keycloak ein Token und leitet dann den Browser an eine URL weiter (Diese ist entweder fest konfiguriert oder diese wurde im Request, die den Login angefordert hat, mitgegeben. In der Regel ist es so, dass ein Pattern verpflichtend ist, also es muss myapp.com als Domain sein. Aber der Login kann von vielen Seiten kommen, die public sind und am Ende möchte an ja wieder auf der Seite sein - nur eben angemeldet)
Bei der Weiterleitung ist im Browser aber nun das Token mit hinterlegt. Das kann das Frontend nun auswerten und erhält dadurch dann gewisse Informationen wie Name, Email Adresse und all sowas....

Wenn das Frontend auf das Backend zugreift, dann wird dieses Token vom Nutzer einfach mitgegeben.

Für die Nutzerdaten selbst ist Keycloak verantwortlich. Das kannst Du soweit konfigurieren. Du kannst also für Login und so eigene Seiten hinterlegen, damit es so aussieht, wie Du willst. Und Du kannst in Keycloak für ein Realm "Enable User Registration" aktivieren.

Wichtig ist, dass die Verantwortung wirklich bei Keycloak liegt. Du solltest da also keine Vertraulichen Informationen in Deiner App verwalten oder pflegen. Du bekommst also nie das Passwort zu sehen. Der User muss sich auch nicht mit Passwort anmelden. Evtl. meldet er sich mit einem Zertifikat an oder mit irgend etwas anderem... Evtl. mit einem anderen Identity Provider wie Microsoft, Google, Facebook, Github, ....

Das ist nicht die Verantwortung Deiner App. Das ist der Verantwortungsbereich von Keycloak. Und das kann man da alles konfigurieren.
Deine Anwendung (Frontend wie Backend) vertrauen der Keycloak Instanz und damit dem Token.
Vielen Dank, das war mir garnicht so klar und ist wirklich hilfreich.

Was meinst du denn aber bitte mit "Der User muss sich auch nicht mit Passwort anmelden. Evtl. meldet er sich mit einem Zertifikat an oder mit irgend etwas anderem"? Weil ich meine der User hat sich doch registriert, dann muss er doch auch das Passwort für seinen Account eingeben, oder habe ich dich da falsch verstanden?

Und setzt Keycloak den Token im Browser dann automatisch? Also ist das dann im local storage gespeichert?

Vielen Dank!
 

KonradN

Super-Moderator
Mitarbeiter
Du hast viele Möglichkeiten, wie sich ein User anmelden kann. Username / Passwort oder Email/Passwort sind nur zwei Möglichkeiten.

Unternehmen haben teilweise eine eigene PKI Infrastruktur und nutzen diese, um sich z.B. dann mit einem Zertifikat auf einer Smartcard anzumelden. Das geht auch mit Keycloak: Server Administration Guide (keycloak.org)

Was alles mit Keycloak geht kann Dir aber als Entwickler egal sein. Du musst die einzelnen Möglichkeiten nicht kennen. Das ist aus meiner Sicht der große Vorteil. Die Userverwaltung ist separat und Du hast damit nichts am Hut. Für Tests kannst Du da irgendwas haben. Die typischen User user/user und admin/admin oder so ... (Also jeweils username/passwort angegeben). Und wenn die Anwendung dann deployed wird, dann kann da genutzt werden, was immer da gewünscht wird.

Damit hast Du eine kritische Komponente ausgelagert. Du musst Dir keine Gedanken machen, was für Features da evtl. benötigt werden. Sicherheitsanforderungen können separat von Deiner Anwendung frei umgesetzt werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Jose05 Umgang mit Exceptions in einen Programm Allgemeine Java-Themen 2
Robert Zenz Ich brauche bitte mal kurz einen Sanity/Reality-Check betreffend Tests. Allgemeine Java-Themen 9
berserkerdq2 Jemand einen Tipp wie man ein Javafx-Hintergrund "dynamisch" macht Allgemeine Java-Themen 3
berserkerdq2 Text über einen Shape anzeigen (Scenebuilder) Allgemeine Java-Themen 1
Lennox Schinkel Java Kara Auf einen Java Host laufen lassen Allgemeine Java-Themen 17
A verschachtelte for-Schleife in einen Stream umwandeln? Allgemeine Java-Themen 4
N Wie mache ich einen UnitTest? Allgemeine Java-Themen 16
D Klassendesign für einen Pascal Interpreter Allgemeine Java-Themen 6
Jose05 Gibt es einen Nachteil bei dem JDK 8? Allgemeine Java-Themen 7
E Objekte in einen String packen und wieder laden Allgemeine Java-Themen 5
O Warum kann ich so keine Elemente löschen und erhalte einen IllegalStateException? Allgemeine Java-Themen 4
M Schleife für einen TicTacToe Computer Allgemeine Java-Themen 5
N Validator für einen SQL-Befehl Allgemeine Java-Themen 22
ZH1896ZH Best Practice Wie erstellt man am besten einen Kalender? Allgemeine Java-Themen 3
R Java Stream: Ist es möglich, einen stream zusammenzufassen Allgemeine Java-Themen 6
Zrebna FileUtils.cleanDirectory() - aber einen sub-Ordner "verschonen" Allgemeine Java-Themen 1
MiMa Datei verschieben hat einen Fehler?? Allgemeine Java-Themen 20
L Generator für einen Parser implementieren Allgemeine Java-Themen 13
W Haben Konstruktoren in Java eigentlich immer mindestens einen Parameter? Allgemeine Java-Themen 4
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
P einen public <Optinal String> in einer anderen Klasse mit einem Int vergleichen Allgemeine Java-Themen 2
A Mithilfe von einer Nummer einen Namen finden n-Beziehung Allgemeine Java-Themen 8
B Long in einen Double umwandeln und im Label anzeigen Allgemeine Java-Themen 7
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
MoxxiManagarm Ich brauche einen smarten Ansatz Allgemeine Java-Themen 23
J Gebautes Jar per Maven in einen Docker Container kopieren Allgemeine Java-Themen 0
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
L File beim Kopieren in einen anderen Ordner umbenennen Allgemeine Java-Themen 6
E Einen Bot Programmieren. Allgemeine Java-Themen 6
F Operationen/Methoden einen WebService im Browser mit Apache Axis aufrufen Allgemeine Java-Themen 4
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
J Einen Thread in einer Schleife Allgemeine Java-Themen 2
P [Webdriver] einen Datensatz signieren Allgemeine Java-Themen 0
R MAC-Adresse eindeutig für einen PC ? Bezug zu Netzwerk, wieso ? Allgemeine Java-Themen 7
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
N Wie öffne ich einen runtergeladadenen Code in IntelliJ Allgemeine Java-Themen 3
R Wie einen ClientBuilder / JarBuilder programmieren? Allgemeine Java-Themen 14
S Input/Output Beste Möglichkeit einen String in einen Datei zu Schreiben Allgemeine Java-Themen 2
L Input/Output Wie kann man in der Konsole einen Text farbig ausgeben z.b in grün Allgemeine Java-Themen 6
L Wie programmiert man einen Listener? Allgemeine Java-Themen 1
M Nanosekunden-Pause innerhalb einen Thread-Loops Allgemeine Java-Themen 3
Thallius Wie convertiere ich einen pkcs8 key in einen java lesbaren? Allgemeine Java-Themen 16
M Was braucht man, um einen Java Job zu bekommen? Allgemeine Java-Themen 8
G Substrings in einen String zusammenfassen Allgemeine Java-Themen 5
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
N Compiler-Fehler Warum erhalte ich einen Nullpointer Fehler? Allgemeine Java-Themen 2
P Zum src Ordner einen Projektes navigieren Allgemeine Java-Themen 8
J Abhängigkeit zwischen Rechenzeit und Speicherbedarf in einen Algorithmus Allgemeine Java-Themen 7
MaxG. Swing Wie kann man einen Dateiordner auswählen ? Allgemeine Java-Themen 3
D Kopieren von Dateien aus einem Ordner in einen anderen Allgemeine Java-Themen 6
KeVoZ_ int Werte in einen String fassen Allgemeine Java-Themen 4
RalleYTN Problem bei Schleife die durch einen 2D raum iterieren soll Allgemeine Java-Themen 1
S Einen Punkt um den Ursprung drehen Allgemeine Java-Themen 5
Tausendsassa Threads Einen Thread sich selbst schließen lassen Allgemeine Java-Themen 17
M Genaues Bugtracking - jemand einen Vorschlag? Allgemeine Java-Themen 14
L Gibt es in Java einen Property Editor? Allgemeine Java-Themen 2
S Einen übergebenen String kopieren Allgemeine Java-Themen 3
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
L Wie kann ich einen Keystore aus existierenden Zertifikaten erstellen? Allgemeine Java-Themen 1
P Vectorelemente in einen anderen Vector kopieren Allgemeine Java-Themen 12
U in java an einen Rückgabewert aus matlab rankommen Allgemeine Java-Themen 2
B einen color-chooser bauen, ähnliche Farben vermeiden Allgemeine Java-Themen 5
B .txt Datei in einen kompletten String konvertieren Allgemeine Java-Themen 20
H Gibt es einen großen Unterschied zwischen Java 6 und Java 7? Allgemeine Java-Themen 3
M String in einen 2D array bringen Allgemeine Java-Themen 2
Y Prüfen ob ein Graph immer einen von mehren Enden erreicht Allgemeine Java-Themen 4
J (Java3D) Einen Faden programmieren - Logikproblem Allgemeine Java-Themen 5
Y Applet/Html - Wie Java-Methode aufrufen, die einen Parameter erwartet? Allgemeine Java-Themen 3
Rudolf In wie fern lohnt sich C++ für einen Javaentwickler Allgemeine Java-Themen 70
A Welches Speichermanagement für einen Kalkulator Allgemeine Java-Themen 7
S OOP Objekte als Return-Werte: Einen Klon zurückgeben oder Instanz auf das Feld? Allgemeine Java-Themen 10
J String-Typ in einen generischen Typ T umwandeln Allgemeine Java-Themen 6
S RandomAcessFile das einen InputStream wrappt..? Allgemeine Java-Themen 2
H Scanner soll einen Inputredirect einlesen, liest aber nicht jedes Wort ein. Allgemeine Java-Themen 3
H Wie erzeugt man einen Daemon? Allgemeine Java-Themen 7
S Wie beendet man einen Process in Java Platform unabhänging? Allgemeine Java-Themen 8
Z Threads Thread für einen Client Allgemeine Java-Themen 9
A nur einen Wert aus einer .conf lesen und erneuern Allgemeine Java-Themen 3
S MANIFEST DATEI hat nur einen Eintrag Allgemeine Java-Themen 14
M Einen Prozess "crashen" lassen Allgemeine Java-Themen 9
I getResponseCode(); returnt einen falschen Wert? Allgemeine Java-Themen 7
U Wie kann mit einen Java Applet Dateien erstellen,verschieben und löschen? Allgemeine Java-Themen 9
C Argument an einen Thread übergeben Allgemeine Java-Themen 4
A Framework für einen Web Service Allgemeine Java-Themen 6
I %AppData% Variable für einen Prozess setzen Allgemeine Java-Themen 23
V Gibt es einen Variablen Cast? Allgemeine Java-Themen 8
S regex für einen Link Allgemeine Java-Themen 3
M Client für einen Webservice erstellen (ONVIF) Allgemeine Java-Themen 3
T Undwandlung eines String in einen InputStream? Allgemeine Java-Themen 3
M Selbst geschriebener InputStreamReader über einen beliebigen InputStream Allgemeine Java-Themen 4
P Datei in einen String lesen Probleme bei Codierung Allgemeine Java-Themen 2
H SwingWorker statt Thread für einen Server Allgemeine Java-Themen 2
G einen Thread beim Schlafen überraschen und abschießen Allgemeine Java-Themen 3
A Variable Parameterinhalte an einen Query übergeben? Allgemeine Java-Themen 3
M einen Tag addieren Allgemeine Java-Themen 11
T In der JVM einen weiteren, unabhängigen Prozess starten Allgemeine Java-Themen 11
Schandro Datei öffnen mit... Bestimmten Dateityp mit einen Java-Programm öffnen lassen Allgemeine Java-Themen 5
B Gibt es einen Unterschied zwischen Java 1.2 und Java 2? Allgemeine Java-Themen 7
T Wie kann ich einen doppelstart vermeiden? Allgemeine Java-Themen 9
G Teilstring in einen String einfügen Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben