Supongo que desea autenticación basada en formularios mediante descriptores de implementación y j_security_check
.
También puede hacer esto en JSF simplemente usando los mismos nombres de campo predefinidos j_username
y j_password
como se muestra en el tutorial.
P.ej
<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>
Puede realizar una carga User
lenta en el getter para verificar si User
ya está conectado y, de lo contrario, verificar si Principal
está presente en la solicitud y, de ser así, obtener el User
asociado 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;
}
}
El User
es obviamente accesible en JSF EL por #{auth.user}
.
Para cerrar sesión, haga un HttpServletRequest#logout()
(y configúrelo User
como nulo) Puede obtener un identificador de HttpServletRequest
en JSF por ExternalContext#getRequest()
. También puede simplemente invalidar la sesión por completo.
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "login?faces-redirect=true";
}
Para el remanente (que define usuarios, roles y restricciones en el descriptor de implementación y el ámbito), solo siga el tutorial Java EE 6 y la documentación del contenedor de servlet de la manera habitual.
Actualización : también puede usar el nuevo Servlet 3.0 HttpServletRequest#login()
para hacer un inicio de sesión programático en lugar de usar el j_security_check
cual no puede ser alcanzado por un despachador en algunos contenedores de servlet. En este caso se puede usar un formulario JSF fullworthy y un grano con username
y password
propiedades y un login
método que se ven así:
<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>
Y esta vista abarcó el bean administrado que también recuerda la página solicitada inicialmente:
@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 esta manera User
se puede acceder a JSF EL por #{user}
.