Ho appena iniziato a imparare Java EE. Il mio obiettivo è implementare un portale web (con EJB 3 e JSF) per i giocatori di badminton, in cui gli utenti possono pubblicare e analizzare i loro risultati.Sicurezza Java EE - Non reindirizzato alla pagina iniziale dopo il login
Per semplificare l'operazione (beh, si scopre che in realtà non lo è) Ho deciso di utilizzare il sistema di sicurezza fornito dal contenitore (JBoss as7). Dopo qualche problema sono riuscito a far funzionare l'autenticazione/autorizzazione. Tuttavia, ho un problema che non sono stato in grado di risolvere.
Quando provo ad accedere a una pagina protetta ottengo, come previsto, intercettato dal sistema di sicurezza. Tuttavia, dopo aver effettuato l'accesso non sono reindirizzato alla pagina inizialmente richiesta. Invece mi viene chiesto ancora una volta di accedere. Se digito manualmente l'indirizzo originale, posso accedere alla pagina senza problemi.
Ho letto molti thread su StackOverflow, ma non sono stato in grado di risolvere il mio problema. Sarei davvero grato se qualcuno potesse aiutarmi!
Authentication.java:
@ManagedBean
@SessionScoped
public class Authentication {
private String username = "";
private String password = "";
private User user = new User();
@EJB
UserService service;
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 User getUser() {
return user;
}
public void login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
try {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(username, password);
user = service.find(username, password);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
return "login";
}
}
login.xhtml
<h:body>
<h:form>
<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{authentication.username}" required="true" />
<h:message for="username" />
<br />
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{authentication.password}" required="true" />
<h:message for="password" />
<br />
<h:commandButton value="Login" action="#{authentication.login()}" />
<h:messages globalOnly="true" />
</h:form>
</h:body>
home.xhtml
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'
xmlns:f='http://java.sun.com/jsf/core'
xmlns:h='http://java.sun.com/jsf/html'
xmlns:ui='http://java.sun.com/jsf/facelets'
xmlns:p="http://primefaces.org/ui">
<h:head>
<link type="text/css" rel="stylesheet"
href="#{request.contextPath}/themes/cupertino/skin.css" />
</h:head>
<h:body>
<h:form>
<h:commandButton action="login" value="Log in" />
</h:form>
</h:body>
web.xml
....
<display-name>BadmintonPortal</display-name>
<welcome-file-list>
<welcome-file>/pages/protected/user/user_home.xhtml</welcome-file>
</welcome-file-list>
<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>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>cupertino</param-value>
</context-param>
<!-- Protected area definition -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - ADMIN Only</web-resource-name>
<url-pattern>/pages/protected/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - USER and ADMIN</web-resource-name>
<url-pattern>/pages/protected/user/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!-- Login page -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/pages/public/login.xhtml</form-login-page>
<form-error-page>/pages/public/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
<!-- System roles -->
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
Edit:
dimenticato di includere faces-config.xml file di
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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-facesconfig_2_1.xsd"
version="2.1">
<navigation-rule>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/pages/protected/user/user_home.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
jboss-web.xml
<?xml version='1.0' encoding='UTF-8'?>
<jboss-web>
<context-root>BadmintonPortal</context-root>
<security-domain>java:/jaas/BadmintonPortalRealm</security-domain>
</jboss-web>
Edit 2:
Soluzione di lavoro
@ManagedBean
@ViewScoped
public class Authentication {
...
public Authentication() {
ExternalContext eContext = FacesContext.getCurrentInstance()
.getExternalContext();
uri = (String) eContext.getRequestMap().get(
RequestDispatcher.FORWARD_REQUEST_URI);
}
public void login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
try {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(username, password);
user = service.find(username, password);
context.getExternalContext().getSessionMap().put("user", user);
context.getExternalContext().redirect(uri);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
} catch (IOException e) {
e.printStackTrace();
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
return "login";
}
}
Quale dominio di sicurezza si sta utilizzando (definito in WEB-INF/jboss-web.xml)? Sembra che non ti stia affidando al modello di autenticazione JBoss al 100%. Il modulo di login dovrebbe seguire questo modello: https://community.jboss.org/wiki/SecureAWebApplicationUsingACustomForm. Se segui questo modello non dovresti aver bisogno di implementare alcun bean di autenticazione. – Toni
Ho aggiunto i file faces-config e jboss-web. Per ora li ho mantenuti il più semplice possibile. Il motivo per cui ho implementato il bean di autenticazione era che potevo usare il tag (e quindi essere in grado di usare primefaces). –
Toss
È interessante, quindi non stai davvero utilizzando il dominio di sicurezza, giusto? – Toni