Hey, ich habe noch so meine Probleme mit einer Benutzerauthentifizierung.
Ich beziehe mich auf diese Anleitung:
Triona Weblog Sicherheit in Java-EE6-Webapplikationen
Zunächst versuche ich zu erklären, was ich gemacht habe:
1. Ich benötigte einen JDBCRealm, also habe ich mir in meiner Oracle-Datenbank eine Tabelle "Benutzer" (ID, Login, Passwort, Rolle) und "Rolle" (ID, Name), sowie einen Testbenutzer mit der Rolle Admin angegelegt. Benutzer.Rolle ist ein Fremdschlüssel auf Rolle.ID.
2. In meinem Projekt habe ich im WEB-INF-Verzeichnis die "glassfish-web.xml" angelegt (Testsystem ist Glasshfish, später wahrscheinlich JBoss). Diese sieht wie folgt aus:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>employee</role-name>
<group-name>employee</group-name>
</security-role-mapping>
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>[/XML]
3. Im Tutorial steht, dass die Datenbank dem Server bekannt gemacht werden muss. Also einen JDBC-Verbindungspool und eine JDBC-Ressource habe ich bereits angelegt. Die Anwendung läuft soweit ja auch bereits. Bedeutet das, ich muss meine Entity-Klasse für die Benutzer noch per JNDI-Bekannt machen?
Unter Ressourcen/JNDI kann ich ja einen neuen JNDI anlegen. Ich vermute mal das ist ein externer JNDI.
JNDI-Name: jdbc/sysbuch
Ressourcentyp: Operator (meine Entity-Klasse für die Benutzer)
Bei Factory-Klasse und JNDI-Suche bin ich überfragt.
Oder benötige ich das garnicht?
EDIT: Sollte eigentlich überflüssig sein, da die Anwendugn ja bereits über die persistence.xml über den JNDI der Datanbankverbindung bescheid weiß.
4. Im Glassfish habe ich den Realm angelegt mit folgenden Daten:
Bereichsname: loginRealm
Klassenname: com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm
JAAS-Kontext: jdbcRealm
JNDI: jdbc/sysbuch (selber Name wie der Verbindungspool)
Benutzertabelle: benutzer
Benutzernamenspalte: login
Passwortspalte: passwort
Gruppentabelle: rolle
Gruppennamenspalte: name (Bezeichnung in der Rollentabelle)
Digest-Algorithmus: none
5. Die Login-Seite und die LoginBean sind sehr ähnlich wie im Tutorial. Die funktionieren auch.
Mein Bean ist auch sehr ähnlich:
6. Zum Schluss habe ich noch die web.xml angepasst, die jetzt wie folgt aussieht:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Producer</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>SysBuchRealm</realm-name>
<form-login-config>
<form-login-page>/faces/login.xhtml</form-login-page>
<form-error-page>/faces/login.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description/>
<role-name>admin</role-name>
</security-role>
<security-role>
<description/>
<role-name>employee</role-name>
</security-role>
</web-app> [/XML]
7. Nun wollte ich mich einloggen und er springt immer in den CATCH-Block der login-Methode.
Vermutlich liegt es an der JNDI-Sache. Ich finde leider nicht allzuviel sinnvolles zu dem Thema bzw. versteh ich es in dem Tutorial nicht so ganz.
Vielen Dank schonmal
Ich beziehe mich auf diese Anleitung:
Triona Weblog Sicherheit in Java-EE6-Webapplikationen
Zunächst versuche ich zu erklären, was ich gemacht habe:
1. Ich benötigte einen JDBCRealm, also habe ich mir in meiner Oracle-Datenbank eine Tabelle "Benutzer" (ID, Login, Passwort, Rolle) und "Rolle" (ID, Name), sowie einen Testbenutzer mit der Rolle Admin angegelegt. Benutzer.Rolle ist ein Fremdschlüssel auf Rolle.ID.
2. In meinem Projekt habe ich im WEB-INF-Verzeichnis die "glassfish-web.xml" angelegt (Testsystem ist Glasshfish, später wahrscheinlich JBoss). Diese sieht wie folgt aus:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>employee</role-name>
<group-name>employee</group-name>
</security-role-mapping>
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>[/XML]
3. Im Tutorial steht, dass die Datenbank dem Server bekannt gemacht werden muss. Also einen JDBC-Verbindungspool und eine JDBC-Ressource habe ich bereits angelegt. Die Anwendung läuft soweit ja auch bereits. Bedeutet das, ich muss meine Entity-Klasse für die Benutzer noch per JNDI-Bekannt machen?
Unter Ressourcen/JNDI kann ich ja einen neuen JNDI anlegen. Ich vermute mal das ist ein externer JNDI.
JNDI-Name: jdbc/sysbuch
Ressourcentyp: Operator (meine Entity-Klasse für die Benutzer)
Bei Factory-Klasse und JNDI-Suche bin ich überfragt.
Oder benötige ich das garnicht?
EDIT: Sollte eigentlich überflüssig sein, da die Anwendugn ja bereits über die persistence.xml über den JNDI der Datanbankverbindung bescheid weiß.
4. Im Glassfish habe ich den Realm angelegt mit folgenden Daten:
Bereichsname: loginRealm
Klassenname: com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm
JAAS-Kontext: jdbcRealm
JNDI: jdbc/sysbuch (selber Name wie der Verbindungspool)
Benutzertabelle: benutzer
Benutzernamenspalte: login
Passwortspalte: passwort
Gruppentabelle: rolle
Gruppennamenspalte: name (Bezeichnung in der Rollentabelle)
Digest-Algorithmus: none
5. Die Login-Seite und die LoginBean sind sehr ähnlich wie im Tutorial. Die funktionieren auch.
Mein Bean ist auch sehr ähnlich:
Java:
@Named("loginPM")
@SessionScoped
public class LoginPM implements Serializable {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String login() {
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
try {
//Login per Servlet 3.0
request.login(username, password);
// Der Principal entspricht dem Usernamen
Principal principal = request.getUserPrincipal();
// Wir können hier nur abfragen, ob der User eine Rolle hat (isUserInRole('whatever')),
// aber wir können NICHT die Rolle aktiv erfragen (z.B. mit getUserRole(...))
if (request.isUserInRole("admin")) {
String msg = "User: " + principal.getName() + ", Role: admin";
fc.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, null));
return "login";
} else if (request.isUserInRole("employee")) {
String msg = "User: " + principal.getName() + ", Role: employee";
fc.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, null));
return "login";
}
return "du_musst_die_rollen_noch_definieren"; // hier sollte etwas sinnvolles passieren ;-)
} catch (Exception e) {
System.out.println("Fehler!");
}
return "login";
}
public void logout() {
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fc.getExternalContext().getSession(false);
if (session != null) {
session.invalidate();
}
fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "/login.xhtml");
}
}
6. Zum Schluss habe ich noch die web.xml angepasst, die jetzt wie folgt aussieht:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Producer</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>SysBuchRealm</realm-name>
<form-login-config>
<form-login-page>/faces/login.xhtml</form-login-page>
<form-error-page>/faces/login.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description/>
<role-name>admin</role-name>
</security-role>
<security-role>
<description/>
<role-name>employee</role-name>
</security-role>
</web-app> [/XML]
7. Nun wollte ich mich einloggen und er springt immer in den CATCH-Block der login-Methode.
Vermutlich liegt es an der JNDI-Sache. Ich finde leider nicht allzuviel sinnvolles zu dem Thema bzw. versteh ich es in dem Tutorial nicht so ganz.
Vielen Dank schonmal
Zuletzt bearbeitet: