Suppongo che tu voglia un'autenticazione basata su form usando descrittori di distribuzione e j_security_check.
Puoi anche farlo in JSF semplicemente usando gli stessi nomi di campo predefiniti j_usernamee j_passwordcome dimostrato nel tutorial.
Per esempio
<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>
È possibile eseguire il caricamento lento in User getter per verificare se Userè già stato effettuato l'accesso e, in caso contrario, verificare se Principalè presente nella richiesta e, in tal caso, quindi ottenere il Userrelativo 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;
}
}
Il Userè ovviamente accessibile in JSF EL da #{auth.user}.
Per disconnettersi, eseguire un HttpServletRequest#logout()(e impostareUser su null!). È possibile ottenere un handle di HttpServletRequestin JSF da ExternalContext#getRequest(). Puoi anche semplicemente invalidare la sessione del tutto.
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "login?faces-redirect=true";
}
Per il residuo (definizione di utenti, ruoli e vincoli nel descrittore di distribuzione e nel regno), basta seguire l'esercitazione Java EE 6 e la documentazione del servletcontainer nel solito modo.
Aggiornamento : è inoltre possibile utilizzare il nuovo Servlet 3.0 HttpServletRequest#login()per eseguire un accesso programmatico anziché utilizzare j_security_checkche potrebbe non essere di per sé raggiungibile da un dispatcher in alcuni servletcontainer. In questo caso puoi usare un modulo JSF completo e un bean conusername e passwordproprietà e un loginmetodo che assomigliano a questo:
<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>
E questa vista ha gestito il bean gestito che ricorda anche la pagina inizialmente richiesta:
@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.
}
In questo modo Userè accessibile in JSF EL da #{user}.