2011-05-31 15 views
6

He probado los contenedores de seguridad predeterminados en Glassfish 3.0.1 y he llegado a la conclusión de que no dedicaré más tiempo a eso. En cambio, quiero controlar la verificación yo mismo. Pero necesito alguna guía para ponerme en el buen camino.Controlar programáticamente el inicio de sesión con Servlet 3.0

Por el momento tengo un UserBean que tiene una función de inicio de sesión/cierre de sesión (ver a continuación). Y no quiero usar el contenedor integrado * j_security_check *, pero use el núcleo JSF 2.0.

Mis preguntas son;

  1. ¿Necesito un ServletFilter para redirigir el tráfico si el usuario no está conectado (si tiene acceso a ciertas carpetas)?
  2. ¿Cómo almaceno User Pricipals después de que el usuario inició sesión correctamente?

Aprecie cualquier ayuda o enlace a un ejemplo, saludos Chris.

PS. Perdón por la agrupación de dos preguntas juntas

@ManagedBean 
@SessionScoped 
public class UserBean { 

private AuthenticateUser authenticateUser; 
... 

public String login() { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); 

    JsfUtil.log("Username : " +authenticateUser.getUserName()); 
    JsfUtil.log("Password : " +authenticateUser.getPassword()); 
    AuthenticateUser authRequest = authenticationFacade.find(authenticateUser); 
    try { 
     if(!authRequest.equals(authenticateUser)) 
      return "/loginError"; 

     request.login(authenticateUser.getUserName(), authenticateUser.getPassword()); 
     return ""; 
    } catch(ServletException e){ 
     JsfUtil.addErrorMessage(e, "Incorrect username or password, please try again."); 
     return "/loginError"; 
    } 

... 
public String logOut() { 
    String result = "/index?faces-redirect=true"; 
    FacesContext context = FacesContext.getCurrentInstance(); 
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); 

    try { 
     request.logout(); 
    } catch (ServletException e) { 
     JsfUtil.log("Failed to logout user!" +e.getRootCause().toString()); 
     result = "/loginError?faces-redirect=true"; 
    } 
    return result; 
    } 

Respuesta

9

Cuando se desea utilizar request.login(), entonces usted realmente debería haber configurado un reino en el contenedor que representa la base de datos de usuario. Pero parece que ha reemplazado el Reino por unos AuthenticationFacade. En este caso, el request.login() no es útil para usted.

Solo tiene que poner al usuario en el alcance de la sesión e interceptarlo. Esto es un ejemplo de patada de salida:

@ManagedBean 
@SessionScoped 
public class UserManager { 

    @EJB 
    private UserService userService; 
    private String username; 
    private String password; 
    private User current; 

    public String login() { 
     current = userService.find(username, password); 

     if (current == null) { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login, try again")); 
      return null; 
     } else { 
      return "userhome?faces-redirect=true"; 
     } 
    } 

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

    public boolean isLoggedIn() { 
     return current != null; 
    } 

    // Getters/setters (but do NOT provide a setter for current!) 
} 

Al tomar la autenticación en las manos de este tipo, entonces definitivamente necesita un filter para restringir el acceso. Cuando se utiliza seguridad administrada por contenedor, normalmente se especifica como <url-pattern> de <security-constraint> para esto. Pero sin eso, debes tomarlo en tus manos. Es bueno saber que los beans gestionados de JSF están codificados por su nombre de bean gestionado en cualquier ámbito.

UserManager userManager = ((HttpServletRequest) request).getSession().getAttribute("userManager"); 

if (userManager == null || !userManager.isLoggedIn()) { 
    ((HttpServletResponse) response).sendRedirect("login.xhtml"); 
} else { 
    chain.doFilter(request, response); 
} 

Localice el filtro de arriba en el patrón de URL deseado.


Cuando todavía quiere reconsiderar el uso de la autenticación gestionado por contenedores, a continuación, las siguientes respuestas relacionadas pueden ser útiles:

+0

Gracias por la súper rápida respuesta. Tal vez no es prudente no usar un dominio del contenedor de la aplicación. Pero tropecé con la patrulla, cuando traté de usar la estructura/diseño de mi mesa. Se siente como una gran caja negra con el reino contenedor. Pero con ServletFilter aún puedo restringir todo el acceso a la raíz y otras carpetas. Así que lo intentaré mañana. Gracias de nuevo. – Chris

+0

De nada. – BalusC

0

Tenga en cuenta si lo es, si está utilizando la seguridad del reino JDBC. Hay algunas palabras fijas/esperadas en los campos donde configura el dominio en la consola de administración de Glassfish.

En el JAAS Contexto: presentada, que tiene que escribir: jdbcRealm. Esta palabra clave hace que el contenedor de seguridad use el reino JDBC esperado. Si escribe algo más, no funcionará.

He aquí un buen ejemplo, hecho por Gordan Jugo; Netbeans/Glassfish JDBC Security Realm

Cuestiones relacionadas