# Benutzerverwaltung richtig/professionell umsetzen



## kendoha (23. Jan 2015)

Hallo Zusammen

Ich habe gerade mein erstes Java EE Webprojekt hinter mir (so gut wie...). Wie ich inzwischen feststellen musste habe ich dabei sehr viel übersehen (kein JSF, CDI, EJP, JPA....). Mit diesen Technologien habe ich mich aber inzwischen auseinandergesetzt und ich werde sie in Zukunft einsetzen.

Es gibt aber ein Thema zu dem ich einfach nichts finde (wahrscheinlich suche ich nicht mit den richtigen Stichwörtern), es geht darum wie man die Benutzerauthentifizierung richtig macht.
Bisher habe ich die DIGEST Methode genommen, die ich über die web.xml gesetzt habe. Als erstes passt mir da schonmal das schlichte Anmeldefenster nicht, ich möchte eine Seite haben. Zweitens habe ich auch das Gefühl nicht genug Kontrolle über das ganze zu haben, ich möchte über ein @SessionScoped Bean die Benutzerinformationen hinterlegen und dabei auch eine Variable setzen können mit der die Session invalidiert werden kann und der User sich neu anmelden muss. (Ist das der richtige Ansatz?)

Mir ist bekannt, dass man auch die FORM als Anmeldemethode nehmen kann, aber so wie ich das verstanden habe werden da die Informationen nicht digested aber das möchte ich unbedingt erhalten.

Ich möchte auch, dass ich nicht einen Realm auf der Datenbank haben muss, den sich alle Applikationen auf dem Server teilen. Ich hätte das lieber so, dass ich die Benutzerdaten für jede Applikation in einer eigenen Datenbank sammeln kann.

Meine Frage bezieht sich auch auf das Allgemeine wie man die Benutzerverwaltung/Authentifizerung richtig umsetzt. Ich möchte eine einfache und global gültige Authentifizierung, so dass ich nicht, wie bisher, auf jedem Servlet in einer if-Abfrage klären muss ob der Benutzer auch die Berechtigungen auf diese Seite hat. (Anscheinend kann man das ja auch über Annotations machen, wie ich erfahren hab)

Danke für eure Hilfe


----------



## ARadauer (23. Jan 2015)

kendoha hat gesagt.:


> Ich möchte eine einfache und global gültige Authentifizierung, so dass ich nicht, wie bisher, auf jedem Servlet in einer if-Abfrage klären muss ob der Benutzer auch die Berechtigungen auf diese Seite hat. (Anscheinend kann man das ja auch über Annotations machen, wie ich erfahren hab)



Das Stichwort ist Servlet Filter. Im Grund kann das bei jedem Request prüfen ob in der Session ein Benutzer Objekt ist. Wenn nicht auf eine Seite zum Anmeldung Umleiten.
Im Kern macht Spring Security nichts anders, wobei halt flexibler und aufwändiger.


----------



## stg (23. Jan 2015)

kendoha hat gesagt.:


> Ich möchte auch, dass ich nicht einen Realm auf der Datenbank haben muss, den sich alle Applikationen auf dem Server teilen. Ich hätte das lieber so, dass ich die Benutzerdaten für jede Applikation in einer eigenen Datenbank sammeln kann.



Hä? Ein Realm ist nicht "auf der Datenbank", sondern wird vom JEE Server verwaltet. Du hast die Nutzerdaten doch in der Datenbank, was spricht dann gegen einen JDBCRealm? Du kannst selbstverständlich auch für jede Anwendung einen eigenen Realm erstellen. Das ist mit Abstand das einfachste und sauberste, was mir hierzu einfällt. 

Einem ServletFilter widerspricht das übrigens nicht, den kann man _zusätzlich_ für besondere zusätzlichen Anforderungen zwischenschalten. In deinerFrage sehe ich jedoch nichts, was diesen Aufwand momentan rechtfertigen würde.


----------



## kendoha (23. Jan 2015)

ARadauer hat gesagt.:


> Das Stichwort ist Servlet Filter. Im Grund kann das bei jedem Request prüfen ob in der Session ein Benutzer Objekt ist. Wenn nicht auf eine Seite zum Anmeldung Umleiten.
> Im Kern macht Spring Security nichts anders, wobei halt flexibler und aufwändiger.



Danke, ich denke das könnte das sein, was ich gesucht habe. Aber wie krieg ich eine erzwungene Neuanmeldung hin, wenn ich DIGEST verwende? Dabei gibt es ja keine Seite auf die ich verweisen könnte...



stg hat gesagt.:


> Hä? Ein Realm ist nicht "auf der Datenbank", sondern wird vom JEE Server verwaltet. Du hast die Nutzerdaten doch in der Datenbank, was spricht dann gegen einen JDBCRealm? Du kannst selbstverständlich auch für jede Anwendung einen eigenen Realm erstellen. Das ist mit Abstand das einfachste und sauberste, was mir hierzu einfällt.



Das Problem ist, dass ich die Authentifizierung folgendermassen einschalte über die web.xml:


```
<security-constraint>
    <web-resource-collection>
      <web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>crm_user</role-name>
    </auth-constraint>
    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <login-config>
    <auth-method>DIGEST</auth-method>
    <realm-name>tomcat_realm</realm-name>
  </login-config>
```

Bei dieser Definition befindet sich aber kein Verweis auf den unten Aufgeführten Realm. Wenn ich also einen zweiten Realm für eine zweite Anwendung definieren würde, woher soll der Server dann wissen welchen er zu nehmen hat? (Btw. ich verwende einen Tomcat Server)


```
<Realm  className="org.apache.catalina.realm.JDBCRealm"
                 digest="MD5"
             driverName="com.mysql.jdbc.Driver"
          connectionURL="jdbc:mysql://localhost:3306/tomcat_realm"
         connectionName="****" connectionPassword="****"
              userTable="tomcat_users" userNameCol="user_name" userCredCol="password"
          userRoleTable="tomcat_users_roles" roleNameCol="role_name" />
```


----------



## stg (25. Jan 2015)

kendoha hat gesagt.:


> Bei dieser Definition befindet sich aber kein Verweis auf den unten Aufgeführten Realm. Wenn ich also einen zweiten Realm für eine zweite Anwendung definieren würde, woher soll der Server dann wissen welchen er zu nehmen hat? (Btw. ich verwende einen Tomcat Server)



Ein Blick in die Tomcat-Doku ist da sehr aufschlussreich:


> Inside a <Context> element - This Realm will be used ONLY for THIS web application.


----------

