Je suppose que vous voulez une authentification par formulaire utilisant des descripteurs de déploiement et j_security_check
.
Vous pouvez également le faire dans JSF en utilisant simplement les mêmes noms de champ prédéfinis j_username
et j_password
comme illustré dans le didacticiel.
Par exemple
<form action="j_security_check" method="post">
<h:outputLabel for="j_username" value="Username" />
<h:inputText id="j_username" />
<br />
<h:outputLabel for="j_password" value="Password" />
<h:inputSecret id="j_password" />
<br />
<h:commandButton value="Login" />
</form>
Vous pouvez effectuer un chargement paresseux dans le User
getter pour vérifier si le User
est déjà connecté et sinon, vérifier si le Principal
est présent dans la requête et si c'est le cas, obtenir le User
associé avec j_username
.
package com.stackoverflow.q2206911;
import java.io.IOException;
import java.security.Principal;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
@ManagedBean
@SessionScoped
public class Auth {
private User user; // The JPA entity.
@EJB
private UserService userService;
public User getUser() {
if (user == null) {
Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
if (principal != null) {
user = userService.find(principal.getName()); // Find User by j_username.
}
}
return user;
}
}
Le User
est évidemment accessible dans JSF EL par #{auth.user}
.
Pour vous déconnecter, faites un HttpServletRequest#logout()
(et définissez-le User
sur null!). Vous pouvez obtenir une poignée de HttpServletRequest
JSF dans ExternalContext#getRequest()
. Vous pouvez également simplement invalider complètement la session.
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "login?faces-redirect=true";
}
Pour le reste (définition des utilisateurs, des rôles et des contraintes dans le descripteur de déploiement et le domaine), suivez simplement le didacticiel Java EE 6 et la documentation servletcontainer de la manière habituelle.
Mise à jour : vous pouvez également utiliser le nouveau Servlet 3.0 HttpServletRequest#login()
pour effectuer une connexion par programme au lieu d'utiliser j_security_check
ce qui peut ne pas être accessible en soi par un répartiteur dans certains conteneurs de servlet. Dans ce cas , vous pouvez utiliser une forme fullworthy JSF et un haricot avec username
et password
propriétés et une login
méthode qui ressemblent à ceci:
<h:form>
<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{auth.username}" required="true" />
<h:message for="username" />
<br />
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{auth.password}" required="true" />
<h:message for="password" />
<br />
<h:commandButton value="Login" action="#{auth.login}" />
<h:messages globalOnly="true" />
</h:form>
Et cette vue a une portée gérée bean qui se souvient également de la page initialement demandée:
@ManagedBean
@ViewScoped
public class Auth {
private String username;
private String password;
private String originalURL;
@PostConstruct
public void init() {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
if (originalURL == null) {
originalURL = externalContext.getRequestContextPath() + "/home.xhtml";
} else {
String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);
if (originalQuery != null) {
originalURL += "?" + originalQuery;
}
}
}
@EJB
private UserService userService;
public void login() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
try {
request.login(username, password);
User user = userService.find(username, password);
externalContext.getSessionMap().put("user", user);
externalContext.redirect(originalURL);
} catch (ServletException e) {
// Handle unknown username/password in request.login().
context.addMessage(null, new FacesMessage("Unknown login"));
}
}
public void logout() throws IOException {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
externalContext.redirect(externalContext.getRequestContextPath() + "/login.xhtml");
}
// Getters/setters for username and password.
}
De cette façon, le User
est accessible dans JSF EL par #{user}
.