Pregunta

Me pregunto lo que el enfoque actual es en relación con la autenticación de usuario para una aplicación web haciendo uso de JSF 2.0 (y si no existen componentes) y Java EE 6 mecanismos centrales (permisos de usuario / VER / cierres de sesión) con información de los usuarios tienen en una entidad JPA. El tutorial Oracle Java EE es un poco escaso en este (sólo se ocupa de los servlets).

Este es sin haciendo uso de un conjunto el otro marco, al igual que la primavera-Seguridad (acegi), o la costura, pero tratando de pegarse esperemos que con el nuevo Java EE 6 plataforma (perfil web) si es posible .

¿Fue útil?

Solución

Después de buscar en la web y tratando de muchas maneras diferentes, esto es lo que me gustaría sugerir para Java EE 6 de autenticación:

Configurar el reino de seguridad:

En mi caso, tuve los usuarios en la base de datos. Así que he seguido este blog para crear un reino JDBC que podría autenticar a los usuarios en base a nombre de usuario y contraseñas con hash MD5 en mi tabla de base de datos:

http: //blog.gamatam. com / 2009/11 / JDBC-realm-configuración-con-glassfish-v3.html

Nota: los post habla acerca de un usuario y una mesa de grupo en la base de datos. Tenía una clase de usuario con un atributo UserType enumeración asignada a través de anotaciones javax.persistence a la base de datos. He configurado el reino con la misma tabla para los usuarios y grupos, utilizando la columna userType como la columna de grupo y funcionó bien.

Uso de autenticación de formulario:

Aún después de la entrada en el blog anterior, configurar el web.xml y sun-web.xml, pero en lugar de utilizar la autenticación básica, formulario (en realidad, no importa cuál utiliza, pero terminó usando FORMULARIO ). Utilizar el estándar HTML, no el JSF.

A continuación, utilice la punta de BalusC anteriormente en la inicialización perezosa la información de usuario de la base de datos. Sugirió que hacerlo en un bean gestionado conseguir el director del contexto caras. Solía, en cambio, un bean de sesión con estado para almacenar información de sesión para cada usuario, por lo que inyecta el contexto de sesión:

 @Resource
 private SessionContext sessionContext;

Con el director, que puede comprobar el nombre de usuario y, mediante el Administrador de EJB de entidad, obtener la información de usuario de la base de datos y almacenar en mi EJB SessionInformation.

Salir:

También busqué la mejor manera de cerrar la sesión. El mejor que he encontrado es el uso de un Servlet:

 @WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"})
 public class LogoutServlet extends HttpServlet {
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   HttpSession session = request.getSession(false);

   // Destroys the session for this user.
   if (session != null)
        session.invalidate();

   // Redirects back to the initial page.
   response.sendRedirect(request.getContextPath());
  }
 }

A pesar de que mi respuesta es muy tarde teniendo en cuenta la fecha de la pregunta, espero que esto ayuda a otras personas que terminan aquí desde Google, al igual que yo.

Ciao,

Vítor Souza

Otros consejos

supongo que desee autenticación basada en formulario rel="noreferrer"> usando descriptores de despliegue y j_security_check.

También puede hacer esto en JSF simplemente usando los mismos nombres de campo predefinied j_username y j_password como se demuestra en el tutorial.

por ejemplo.

<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>

Usted puede hacer la carga diferida en el captador User para comprobar si el User ya está conectado y si no, a continuación, comprobar si el Principal está presente en la solicitud y si es así, a continuación, obtener la User asociado con 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 obviamente accesible en JSF EL por #{auth.user}.

Para cerrar la sesión hacer un HttpServletRequest#logout() (User y establecer en nulo!). Se puede conseguir una manija de la HttpServletRequest en JSF por ExternalContext#getRequest() . También se puede simplemente invalidar la sesión por completo.

public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "login?faces-redirect=true";
}

Para el resto (la definición de usuarios, funciones y limitaciones en el descriptor de despliegue y el reino), sólo tiene que seguir el tutorial de Java EE 6 y la documentación servletcontainer la forma habitual.


Actualizar : se puede también utilizar el nuevo Servlet 3.0 HttpServletRequest#login() para hacer un inicio de sesión de programación en lugar de utilizar j_security_check que puede no per-se ser alcanzable por una despachador en algunos servletcontainers. En este caso se puede usar una forma fullworthy JSF y un frijol con propiedades username y password y un método login que se parecen a esto:

<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 este punto de vista de ámbito de frijol que también recuerda la página solicitada inicialmente dirigía:

@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 el User es accesible en JSF EL por #{user}.

Se debe mencionar que se trata de una opción de dejar por completo los problemas de autenticación al controlador frontal, por ejemplo, un servidor web y Apache evaluar la HttpServletRequest.getRemoteUser () en lugar, que es la representación JAVA para la variable de entorno REMOTE_USER. Esto permite también registro de diseños sofisticados en como la autenticación Shibboleth. Las solicitudes de filtrado a un contenedor de servlets través de un servidor web es un buen diseño para entornos de producción, a menudo mod_jk se utiliza para hacerlo.

El tema HttpServletRequest.login no establece estado de autenticación en sesión se ha fijado en 3.0.1. Actualizar glassfish a la última versión y ya está.

La actualización es muy sencillo:

glassfishv3/bin/pkg set-authority -P dev.glassfish.org
glassfishv3/bin/pkg image-update
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top