Michi: Login und User-Objekt mit Java/Tomcat

Hallo Forum,

ich würde unter Tomcat/Java ein Loginbereich für Mitglieder machen und frage mich, wie ich dies am besten und relativ sichersten gestalten soll.

1. Ich erstelle auf Loginseite.jsp eine Loginmaske und lasse dem Mitglied Benutzername und Passwort eingeben und an die Datei Checking.jsp schicken (Leider werden die Daten zwar unverschlüsselt verschickt, aber in HTTPS werden wir uns erst im nächsten Semester vertiefen)

2. Ich empfange Username und Passwort und vergleiche, ob es diesen User mit diesem Passwort in der DB gibt. Falls ja bilde ich ein User-Objekt von der DB-Tabelle mit vielen Daten (Username, Alter, Wohnort, PLZ, Geschlecht, usw.) und speichere das Objekt in die Session. In die DB speichere ich die aktuelle SessionID.

3. Sobald der User auf weitere Seiten klickt, wird im Header der JSP-Seiten immer das User-Objekt von der Session geholt. Falls das Objekt nicht "null" ist, wäre der User authentifiziert, falls nicht, hätte er keine Berechtigung und die JSP-Seite wird nicht aufgebaut bzw. redirected. Sollte ich Zwecks Überprüfung zusätzlich zum Objekt, welches in der Session gespeichert ist auch andere Daten jedesmal prüfen?

4. Beim Logout wird einfach die Session gekillt und aus der DB gelöscht.

Wäre dies irgendwie fahrlässig oder was müsste ich noch dabei achten?

Was ich mir noch die ganze Zeit überlege, wie ich das User-Objekt gestalten sollte und welche Daten ich von dem jeweiligen User reinpacken sollte. (eine Single- und Spielcommunity). Zusätzlich überlege ich mir für die DB-Anbindung "Hibernate" heranzuziehen, wobei evtl. eigene Klassen auch ausreichen würden. Wenn ich eigene Daten von dem User-Objekt brauche, packe ich das beim Login gleich in das Objekt und mache später, falls man mehr braucht (Hobbies, Vorlieben, Emailadresse...) eine zusätzliche Select-Abfrage.
Falls man sich auf andere Profile klickt, hole ich einfach mit einem Select all die nötigen Daten des anderen Benutzers in ein Array, bzw. Vector und platziere die einzelnen Ausgaben auf der jweiligen Profilseite.

Der Anfangsplanung ist irgendwie schwierig, wenn man ein Projekt startet, damit man später bei Änderung bzw. Erweiterung etwas flexibel ist.

Grüße

  1. Hallo Michi,

    1. Ich empfange Username und Passwort und vergleiche, ob es diesen User mit diesem Passwort in der DB gibt. Falls ja bilde ich ein User-Objekt von der DB-Tabelle mit vielen Daten (Username, Alter, Wohnort, PLZ, Geschlecht, usw.) und speichere das Objekt in die Session. In die DB speichere ich die aktuelle SessionID.

    Die Speicherung der Session-Objekte übernimmt ja wohl der Servlet-Container o.ä. Wieso schreibst Du dann noch irgend welche Session-Information in die Datenbank? Das einzige, was Du damit zumachen scheinst, ist, diese wieder zu löschen. Was ist denn, wenn die Session verfällt und automatisch gelöscht wird. Wird dann Deine Session-Id in der Datenbank auch wieder gelöscht?

    Wenn ich eigene Daten von dem User-Objekt brauche, packe ich das beim Login gleich in das Objekt und mache später, falls man mehr braucht (Hobbies, Vorlieben, Emailadresse...) eine zusätzliche Select-Abfrage.

    Hibernate kann so etwas automatisch. Ich bin nicht ganz sicher, ob atomare Eigenschaften eines Objektes auch erst bei bedarf nachgeladen werden können, aber es dürfte auch nicht entscheidend sein, ob ein paar solcher Eigenschaften mehr geladen werden. Weitere Objekte für Verweise auf andere Tabellen können aber auf jeden Fall erst bei Bedarf erzeugt werden.

    Grüße

    Daniel

    1. Hey Danke für die Antwort.

      Die Speicherung der Session-Objekte übernimmt ja wohl der Servlet-Container o.ä. Wieso schreibst Du dann noch irgend welche Session-Information in die Datenbank? Das einzige, was Du damit zumachen scheinst, ist, diese wieder zu löschen. Was ist denn, wenn die Session verfällt und automatisch gelöscht wird. Wird dann Deine Session-Id in der Datenbank auch wieder gelöscht?

      oh, ich merke gerade dass die Seicherung der Session-ID in die DB nutzlos ist.

      Wenn ich eigene Daten von dem User-Objekt brauche, packe ich das beim Login gleich in das Objekt und mache später, falls man mehr braucht (Hobbies, Vorlieben, Emailadresse...) eine zusätzliche Select-Abfrage.
      Hibernate kann so etwas automatisch. Ich bin nicht ganz sicher, ob atomare Eigenschaften eines Objektes auch erst bei bedarf nachgeladen werden können, aber es dürfte auch nicht entscheidend sein, ob ein paar solcher Eigenschaften mehr geladen werden. Weitere Objekte für Verweise auf andere Tabellen können aber auf jeden Fall erst bei Bedarf erzeugt werden.

      Das nachladen, bzw. neu selektieren von zusätzlichen Details zum Benutzer wollte ich mir ersparen, damit ich weniger Anfragen zur DB stelle. Dafür hätte ich dann, wenn ich beim ersten Selektieren viel hole und nen dicken Objekt habe und den von Seite zu Seite herumschleife.

      Was ich zwecks Sicherheit nachfragen wollte. Ich habe gehört, dass man von Session auch die darin gespeicherten Objekte auslesen könnte, falls dies von einem anderen ergattert ist. Geht das problemlos? Dann müsste ich auch aufpassen, was ich alles da herunue. Wollte nämlich evtl. die DB-Verbindung evtl. in die Session speichern, wenn ein User eine Seite aufruft.
      Sobald ich dann ein Select bräuchte, müsste ich das Objekt nur von der Session holen und mit einer statischen Methode die Daten von der DB holen.

      Doch nicht so gut der Gedanke dann.

      Grüße

      1. Hallo Michi,

        Das nachladen, bzw. neu selektieren von zusätzlichen Details zum Benutzer wollte ich mir ersparen, damit ich weniger Anfragen zur DB stelle. Dafür hätte ich dann, wenn ich beim ersten Selektieren viel hole und nen dicken Objekt habe und den von Seite zu Seite herumschleife.

        Diese Objekte werden ja auch wieder serialisiert oder in einer Datenbank abgelegt (jedenfalls vermute ich das, der Servlet-Container kann sie natürlich auch einfach im Speicher halten, bei vielen Sessions ist das aber sicher keine gute Idee). Daher kann es durchaus schlechter oder genau so schlecht sein, die Daten in der Session mit zu schleppen, als sie bei Bedarf erneut aus der Datenbank zu holen.
        So lang es dabei nur um ein paar Eigenschaften geht, die in einer Tabelle stehen, würde ich mir da aber nicht so viele Gedanken machen.

        Was ich zwecks Sicherheit nachfragen wollte. Ich habe gehört, dass man von Session auch die darin gespeicherten Objekte auslesen könnte, falls dies von einem anderen ergattert ist. Geht das problemlos?

        Zum Browser wird ja nur die SessionID übertragen. Um eine Session zu übernehmen, muss ein Angreifer diese SessionID herausfinden. Wenn er sie hat, kann er alles tun, was der "Besitzer" der Session tun könnte. Die in der Session gespeicherten Daten liegen aber nur auf dem Server, an diese kommt er also nicht direkt ran. Natürlich kann er Daten über die Weboberfläche einsehen, die ein Benutzer selbst einsehen könnte.

        Wollte nämlich evtl. die DB-Verbindung evtl. in die Session speichern, wenn ein User eine Seite aufruft.

        Das ist aus mehreren Gründen keine gute Idee.

        • Session-Objekte müssen serialisierbar sein, Objekte, die irgend welche externen Resourcen repräsentieren, sind das typischerweise nicht.
        • Man will nicht für jede Session eine Datenbankverbindung aufmachen, da das sehr viele werden können. Man macht also nur so viele Datenbankverbindungen auf, wie man gleichzeitig benötigt.
        • Datenbankverbindungen werden typischerweise in einem Pool vorgehalten, sodass sie für beliebige Anfragen wiederverwendet werden können. Hibernate verwaltet Datenbankverbindungen auch so. Es ist normalerweise nicht nötig, für eine Session eine eigene Datenbankverbindung zu verwenden.

        Der Lehrbuch-gerechte Ansatz wäre wohl, in der Session entweder die Benutzer-ID oder ein Benutzer-Objekt zu speichern und sich um das nachladen evtl. notwendiger Daten keine Gedanken zu machen, sondern dies Hybernate zu überlassen.

        Man würde also für jeden Request das Benutzer-Objekt aus der Session laden, sich eine DB-Verbindung aus dem Pool holen und eine Transaktion starten, das Objekt wieder an die Transaktion binden (das muss man explizit tun, wenn man Datenobjekte über mehrere Transaktionen hinweg verwendet.)
        Anschließend kann man mit dem Objekt weiterarbeiten, ohne sich um irgend etwas zu kümmern.

        Grüße

        Daniel