Benutzerauthorisierung, User-Login, Anmeldeseite - wie am besten?

Andron

Erfahrenes Mitglied
Benutzerauthorisierung, User-Login, Anmeldeseite - wie am besten? BITTE UM HILFE

Hallo,
ich möchte eine Anmelde-Seite einrichten. Habe auch einiges gelesen und wie es aussieht, gibt es mehrere Möglichkeiten:

- Einstellungen in der Tomcat-konfiguration
- Einfache DB-Vergleiche
- Servlet-Filter
... und noch einiges mehr.


Welche Vorgehensweise würdet ihr mir empfehlen?
Welche ist einfacher und gleichzeitig auch sicher?
Danke
 
Zuletzt bearbeitet:
Hallo,

erstmal muss man bei diesem Thema zwischen Authentisierung (Wer bist du?) und Authorisierung
(Was darfst du?) unterscheiden.

Für Authentisierung über eine zentrale Login-Komponente bietet sich in der JEE WebApp-Welt
beispielsweise ein einfacher (Tomcat)Realm an. Diesen Konfigurierst du zum einen über deinen
Servlet Container und zum anderen über die web.xml. Im Grunde genommen erledigt dann der Realm für dich die Arbeit des Abgleichs der eingegebenen Benutzerdaten mit denen in der Datenbank. Den Realm kannst du so konfigurieren, dass bestimmte URL-Muster von diesem geschützt werden. Ruft nun ein noch nicht authentisierter Benutzer (keine Userinformationen in der Session, keine Cookies) eine geschützte Seite des Realms auf, so wird dieser sofort
auf die Loginseite umgeleitet. (Das passiert intern über einen ServletFilter) Nach der Eingabe von gültigen Benutzerdaten wird der Benutzer nach dem klick auf "login" wieder zur ursprünglich angefragten Resource weitergeleitet.

Hier ein kleines Beispiel für Tomcat:
http://www.tutorials.de/forum/j2ee/189049-tomcat-login-mechanismus.html

Hier ein kleines Beispiel für JBoss 4.x
http://www.tutorials.de/forum/j2ee/208655-beispiel-thema-websecurity-jboss-4-0-2-a.html


Für Authorisierung würde sich ein ServletFilter bzw. ein Interceptor-basierter Ansatz lohnen, welcher die reine Überprüfungslogik (darf der Benutzer diese Funktion verwenden?) kapselt.
Damit lassen sich dann beispielse Authorisierungen deklarativ konfigurieren ( für jede Methode, Klasse, etc.). AOP (Spring AOP, AspectJ) sind auch zwei beliebte Frameworks um deklarative Authorisierung zu implementieren.

Neben eigenen Lösungen gibt es für das Problem (wie immer in der Java Welt :-) natürlich zahlreiche open source Lösungen:
http://www.acegisecurity.org/
http://www.ja-sig.org/products/cas/index.html
http://www.josso.org/

... um die interessantesten mal zu nennen.

Gruß Tom
 
Danke für die detailierte Antwort.
Ich habe hier ein Buch vor mir liegen: Tomcat5 Einsatz in Unternehmensanwendungen mit JSP und Servlets von Lajos Moczar.
Dort ist die formularbasierte Authentifizierung beschrieben, die folgendermaßen aussieht:

Es gibt eine Login-Seite für die FORM-Authentifizierung, also ein Formular mit Eingabefeldern, die heißt login.jsp.
Dann gibt es eine Fehlerseite, error.jsp.

Auszug aus der web.xml:
Code:
<security-constaint>
    <display-name>Scheduler Authentication</display-name>
    <web-resource-collection>
        <web-resource-name>SchedulerServlet</web-resource-name>
        <url-pattern>/main/*</url-pattern
    </web-resource-collection>
    <auth-constraint>
        ...
    </auth-constraint>
</security-constaint>

<login-config>
 ...
</login-config>

<security-role>
 ...
</security-role>

Als role-name werden zwei Rolen festgelegt und in der Datei unleashed-users.xml samt Passwörtern abgelegt.
Im Buch ist also Beschieben, wie man Rollen anlegt und Passwörter definiert.
Und der Datenabgleich findet mit den Daten in der Datei unleashed-users.xml statt.

Wie kann ich das auf mein Problem umstellen?
In welchem Teil soll ich die Daten mit der DB abgleichen, da ich keine unleashed-users.xml haben möchte?

Im <web-resource-name>SchedulerServlet</web-resource-name> wird ein Servlet angegeben, ich nehme an, der ist für die Anfragen zuständig.
Könnte ich dort die Daten vergleichen?
Oder gibt es andere bessere Möglichkeit?

Ich werde mir mal die beiden Links ansehen, vielleicht finde ich dort was.
 
Ok, habe mir den Link http://www.tutorials.de/forum/j2ee/189049-tomcat-login-mechanismus.html angesehen.
Ist dasselbe, was ich auch habe.
Mein Problem bleibt aber immer noch.
Hier:
Code:
 <role rolename="authUser"/>
 <user username="testuser" password="test" roles="authUser"/>
werden die User schon festgelegt.
Ich möchte aber die Daten mit der DB vergleichen.
Nur wo soll das geschehen, weiß ich noch nicht.

EDIT: Habe mir nun den zweiten Link angesehen, der erklärt mir schon einiges, scheint aber komplizierter zu sein.
Ich habe an folgendes Szenario gedacht:

User ruft eine Seite auf.
Es wird eine login-Seite angezeigt.
Wenn User sich vorher nicht registriert hat, kann er auf "Registrieren" klicken und seine Daten eintragen, die werden dann in die DB gespeichert.
Wenn der User seine Daten nun angibt auf der login.jsp, werden diese zum Servlet "CheckerServlet" per POST übertragen.
Der Servlet hat nun die Daten und kann diese mit der Datenbank abgleichen.
Es wird also eine Verbinung zur DB aufgebaut und die Daten werden geprüft.
Wenn alles stimmt, wird der benutzer auf die vorher angegebene oder eine Standard-Seite geforwardet.
Gleichzeit wird dem Benutzer eine Session-ID zugeweisen und diese auch in der DB abgelegt. Die Session-ID wird nach 30 min. ungültig. Wenn der Benutzer die Seite verlässt und wieder aufruft, so hat er ja eine andere Session-ID, somit wird die alte ungültig und der User muss sich dann wieder einloggen.

Ich bin für alle Kommentare und Tipps dankbar.
 
Zuletzt bearbeitet:
Danke, das ist es, was ich gesucht habe,denke ich.

Ich werde das bis Ende der Woche testen und melde mich wieder.

Danke nochmals.
 
So, nun poste ich hier meine Fortschritte, wenn es die überhaupt gibt.

Zuerst habe ich die Datei web.xml angelegt:

Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
 
 <!DOCTYPE web-app
 	PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 	"http://java.sun.com/dtd/web-app_2_3.dtd">
 
 <web-app>
   <display-name>A</display-name>
   <description>
 	A Simple test
   </description>
 
  <security-constraint>
    <display-name>A Configuration Security Constraint</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <!-- Define the context-relative URL(s) to be protected 
      In dem Fall wollen wir einfach unsere index.html schützen.
      -->
      <url-pattern>*.html</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>authUser</role-name>
    </auth-constraint>
  </security-constraint>
	
 <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>A Server Configuration Form-Based Authentication Area</realm-name>
    <form-login-config>
      <form-login-page>/login.jsp</form-login-page>
      <form-error-page>/error.jsp</form-error-page>
    </form-login-config>
  </login-config>

  <security-role>
    <description>
      The role that is required to log in to the A Application
    </description>
    <role-name>authUser</role-name>
  </security-role>
 </web-app>


Danach die server.xml geändert, folgende Zeilen waren auskommentiert, ich habe die ein wenig angepasst :

Code:
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="com.mysql.jdbc.Driver"
          connectionURL="jdbc:mysql://localhost:3306/meinedb"
         connectionName="root" connectionPassword="meinpass"
              userTable="users" userNameCol="user_name" userCredCol="user_pass" />

Danach folgende Tabelle erzeugt:

Code:
mysql> describe users;
+----------------+-----------------+-------+-------+----------+-----------------------+
| Field          | Type          | Null  | Key | Default | Extra               |
+----------------+-----------------+-------+-------+----------+-----------------------+
| id              | int(11)        | NO   | PRI | NULL    | auto_increment |
| user_name | varchar(15) | NO   |       |             |                        |
| user_pass  | varchar(15) | NO   |       |             |                        |
+----------------+-----------------+-------+------+-----------+-----------------------+

In der Tabelle wurde ein User mit user_name und user_pass erzeugt.

Das funktioniert aber nicht.
Ich bekomme die login.jsp angezeigt, nach der Eingabe meiner Daten, bekomme ich folgendes:

Code:
HTTP Status 403 - Access to the requested resource has been denied

--------------------------------------------------------------------------------

type Status report

message Access to the requested resource has been denied

description Access to the specified resource (Access to the requested resource has been denied) has been forbidden.

Außerdem kommt folgende Fehlermeldung:
Code:
17.02.2007 17:47:25 org.apache.catalina.realm.JDBCRealm getRoles
SCHWERWIEGEND: Exception performing authentication
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your S
QL syntax; check the manual that corresponds to your MySQL server version for th
e right syntax to use near 'null WHERE user_name = 'usr'' at line 1
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:3176)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.ja
va:1153)
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:
1266)
        at org.apache.catalina.realm.JDBCRealm.getRoles(JDBCRealm.java:629)
        at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:421)
        at org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:347)
        at org.apache.catalina.authenticator.FormAuthenticator.authenticate(Form
Authenticator.java:257)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentica
torBase.java:416)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
a:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.p
rocessConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo
int.java:527)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFol
lowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
ool.java:684)
        at java.lang.Thread.run(Thread.java:619)




Was habe ich falsch gemacht?
Bitte um Hilfe.
 
Zuletzt bearbeitet:
Ich glaube, das Problem wurde gelöst.
Es fehlte Tabelle user_roles und entsprechende Einträge in der server.xml.
Muss ich den user_role vergeben?
Ich dachte, es geht auch ohne.
Na ja, falls wieder was ist, melde ich mich.
 
Hallo,

du solltest dir mal die Doku zum JDBCRealm durchlesen...
http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#JDBCRealm
Dort steht drin welche Tabellen und Spalten du für den Standard Login-Mechanismus brauchst (... ja du brauchst die user_role mapping Tabelle).

Wie du sicherlich schon bemerkt hast ist der Standard JDBCRealm sehr unflexibel was das Datenbankschema angeht... wie schon gesagt würde ich dir empfehlen auf ACEGI Security oder Josso zu wechseln.

Gruß Tom
 
Es klappt, aber nicht so, wie ich es möchte.
Habe mir die Seiten mit josso und jaas angeschaut, ziemlich kompliziert würde ich sagen.
Ich habe hier ein Ablaufdiagramm erstellt, wie es ungefähr aussehe soll:
log.jpg



Erklärung:
Die User rufen meine Seite auf und werden immer auf eine Instanz weitergeleitet, die zuerst überprüft, ob der User bereits eingeloggt ist oder nicht (Hier habe ich schon Schwierigkeiten Filter oder Mapping?).
Falls der User schon eingeloggt war, kommt er in den security-Bereich. Der Aufruf wird von einem Servlet empfangen, der dann entscheidet, welche jsp - Seite aufgerufen werden soll.
Wenn nich, wird er auf die login.jsp verwiesen, wo er seine Daten eingeben muss. Danach findet Datenbagleich mit der Datenbank statt. Wenn die Daten stimmen, kommt er, wie oben, zu einem Servlet.

Wie programmiere ich das am besten?
Wie kann ich unterscheiden, ob der User schon eingeloggt war oder nicht?
Muss ich dafür immer seine Session-ID überprüfen, ob die in der Datenbank vorhanden ist oder nicht?
Bitte um Hilfe.
 

Neue Beiträge

Zurück