Después de buscar en la Web y probar muchas formas diferentes, esto es lo que sugeriría para la autenticación Java EE 6:
Configure el reino de seguridad:
En mi caso, tenía los usuarios en la base de datos. Así que seguí esta publicación de blog para crear un Reino JDBC que pudiera autenticar a los usuarios según el nombre de usuario y las contraseñas hash MD5 en mi tabla de base de datos:
http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html
Nota: la publicación habla de un usuario y una tabla de grupo en la base de datos. Tenía una clase de usuario con un atributo de enumeración UserType asignado a través de anotaciones javax.persistence a la base de datos. Configuré el reino con la misma tabla para usuarios y grupos, usando la columna userType como la columna del grupo y funcionó bien.
Usar autenticación de formulario:
Aún siguiendo la publicación de blog anterior, configure su web.xml y sun-web.xml, pero en lugar de usar la autenticación BÁSICA, use FORM (en realidad, no importa cuál use, pero terminé usando FORM). Use el HTML estándar, no el JSF.
Luego use la sugerencia de BalusC anterior sobre la inicialización diferida de la información del usuario desde la base de datos. Sugirió hacerlo en un bean administrado obteniendo el director del contexto de caras. En su lugar, utilicé un bean de sesión con estado para almacenar información de sesión para cada usuario, así que inyecté el contexto de la sesión:
@Resource
private SessionContext sessionContext;
Con el director, puedo verificar el nombre de usuario y, usando el Administrador de Entidades EJB, obtener la información del Usuario de la base de datos y almacenarla en mi SessionInformation
EJB.
Cerrar sesión:
También busqué la mejor forma de cerrar sesión. El mejor que he encontrado es usar 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());
}
}
Aunque mi respuesta es muy tardía considerando la fecha de la pregunta, espero que esto ayude a otras personas que terminan aquí desde Google, tal como lo hice yo.
Ciao
Vítor Souza
HttpServletResponse#login(user, password)
, de esa manera puede obtener de DB la sal del usuario, las iteraciones y lo que sea que use para salar, agregue la contraseña que el usuario ingresó usando esa sal y luego solicite al contenedor que se autentique conHttpServletResponse#login(user, password)
.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
yj_password
como se muestra en el tutorial.P.ej
Puede realizar una carga
User
lenta en el getter para verificar siUser
ya está conectado y, de lo contrario, verificar siPrincipal
está presente en la solicitud y, de ser así, obtener elUser
asociadoj_username
.El
User
es obviamente accesible en JSF EL por#{auth.user}
.Para cerrar sesión, haga un
HttpServletRequest#logout()
(y configúreloUser
como nulo) Puede obtener un identificador deHttpServletRequest
en JSF porExternalContext#getRequest()
. También puede simplemente invalidar la sesión por completo.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 elj_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 conusername
ypassword
propiedades y unlogin
método que se ven así:Y esta vista abarcó el bean administrado que también recuerda la página solicitada inicialmente:
De esta manera
User
se puede acceder a JSF EL por#{user}
.fuente
j_security_check
podría no funcionar en todos los contenedores de servlet.@WebServlet(name="testServlet", urlPatterns={"/ testServlet "}) @ServletSecurity(@HttpConstraint(rolesAllowed = {"testUser", "admin”}))
Y por método nivel:@ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"), @HttpMethodConstraint(value="POST", rolesAllowed={"testUser"})})
FacesServlet
y no puedes (y no quieres) modificarlo.RequestDispatcher.FORWARD_REQUEST_URI
. Los atributos de solicitud están en JSF disponibles porExternalContext#getRequestMap()
.Cabe mencionar que es una opción dejar completamente los problemas de autenticación al controlador frontal, por ejemplo, un servidor web Apache y evaluar el HttpServletRequest.getRemoteUser (), que es la representación de JAVA para la variable de entorno REMOTE_USER. Esto también permite diseños de inicio de sesión sofisticados, como la autenticación Shibboleth. Filtrar solicitudes a un contenedor de servlets a través de un servidor web es un buen diseño para entornos de producción, a menudo se usa mod_jk para hacerlo.
fuente
El problema HttpServletRequest.login no establece el estado de autenticación en la sesión se ha solucionado en 3.0.1. Actualice glassfish a la última versión y ya está.
La actualización es bastante sencilla:
fuente