Interceptores en Struts 2

Diferencias entre interceptores y filtros en Struts:

Filtros: Aplican a todas las peticiones HTTP, incluyendo recursos estáticos como CSS, JavaScript, imágenes, etc.

Interceptores: Solo interceptan las acciones (actions) del framework Struts 2. Son componentes específicos del framwork.

Configuración de interceptores.

1. Crear una clase que herede de AbstractInterceptor

2. Configurar en struts.xml

  1. Agregar la sección <interceptors> con la configuración del interceptor.
  2. Referenciar el interceptor en la acción correspondiente.

Consideraciones importantes:

  1. Las acciones deben incluir la referencia a defaultStack
  2. Es posible crear un interceptor-stack que incluya defaultStack, y luego referenciar este stack directamente.
<?xml version="1.0" encoding="UTF-8" ?>


<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">
    
        <interceptors>
            <interceptor name="verificadorAcceso" class="com.ejemplo.struts.util.VerificadorAcceso"></interceptor>
                <interceptor-stack name="pilaPersonalizada">
                <interceptor-ref name="verificadorAcceso"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>            
         </interceptors>
        <action name="*_*" class="com.ejemplo.struts.controlador.{1}Accion" method="{2}">
         <!-- Referencia directa a pilaPersonalizada -->
        <interceptor-ref name="pilaPersonalizada"></interceptor-ref>
            <result>
                {1}_{2}.jsp
            </result>
        </action>
    </package>

</struts>

Uso de objetos integrados en interceptores.

Para obtener la sesión:

  1. Mediante ActionContext para obtener un Map.
  2. Usando ServletActionContext
  3. Implementando la interfaz SessionAware

*****************************************************************

Ejemplo: Implementar verificación de inicio de sesión con interceptores.

Existen dos acciones que no deben ser interceptadas: la acción de login y la acción que procesa el inicio de sesión.

En el método de autenticación, se consideran dos escenarios:

  1. Primer inicio de sesión: la sesión no contiene información, por lo que se debe agregar.
  2. Sesión ya estiblecida: la sesión ya contiene infromación, no es necesario agregar datos.

Creación de la clase Usuario:

package com.ejemplo.struts.modelo;

public class Usuario {
    private String nombreUsuario;
    private String contrasena;
    
    public String getNombreUsuario() {
        return nombreUsuario;
    }
    
    public void setNombreUsuario(String nombreUsuario) {
        this.nombreUsuario = nombreUsuario;
    }
    
    public String getContrasena() {
        return contrasena;
    }
    
    public void setContrasena(String contrasena) {
        this.contrasena = contrasena;
    }
}

Archivo de configuración struts.xml

<?xml version="1.0" encoding="UTF-8" ?>


<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">
        <interceptors>
            <interceptor name="verificadorAcceso" class="com.ejemplo.struts.util.VerificadorAcceso"></interceptor>
            <interceptor name="interceptorLogin" class="com.ejemplo.struts.util.InterceptorLogin"></interceptor>
                <interceptor-stack name="pilaCompleta">
                <interceptor-ref name="verificadorAcceso"></interceptor-ref>
                <interceptor-ref name="interceptorLogin"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>            
        </interceptors>
        <global-results>
            <result name="sinSesion">Inicio_sesion.jsp</result>
        </global-results>
        <!-- Acciones de login y home no deben ser interceptadas -->
        <action name="Inicio_sesion" class="com.ejemplo.struts.controlador.InicioSesionAccion" method="mostrarFormulario">
            <result>Inicio_sesion.jsp</result>
        </action>
        <action name="Inicio_verificar" class="com.ejemplo.struts.controlador.InicioSesionAccion" method="verificarCredenciales">
            <result>Inicio_verificado.jsp</result>
        </action>
        <action name="*_*" class="com.ejemplo.struts.controlador.{1}Accion" method="{2}">
            <interceptor-ref name="pilaCompleta"></interceptor-ref>
            <result>
                {1}_{2}.jsp
            </result>
        </action>
    </package>

   
</struts>

Clase de acción

package com.ejemplo.struts.controlador;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.ejemplo.struts.modelo.Usuario;
import com.opensymphony.xwork2.ActionSupport;

public class InicioSesionAccion extends ActionSupport {
    private HttpSession sesion = ServletActionContext.getRequest().getSession();
    private Usuario usuario;
    private List<String> usuariosValidos;
    
    public InicioSesionAccion() {
        // Simulación de base de datos de usuarios válidos
        usuariosValidos = List.of("admin", "operador", "supervisor");
    }
    
    public Usuario getUsuario() {
        return usuario;
    }

    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    public String mostrarFormulario(){
        return SUCCESS;
    }
    
    public String verificarCredenciales(){
        // Verificar si el usuario ya tiene sesión activa
        Object usuarioEnSesion = sesion.getAttribute("usuarioActual");
        if(usuarioEnSesion == null){
            if(usuario != null){
                if(usuariosValidos.contains(usuario.getNombreUsuario())){
                    sesion.setAttribute("usuarioActual", usuario.getNombreUsuario());
                    return SUCCESS;
                } else {
                    return "sinSesion";
                }
            } else {
                return "sinSesion";
            }    
        } else {
            return SUCCESS;
        }    
    }

}

Clase del interceptor

package com.ejemplo.struts.util;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class InterceptorLogin extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocacion) throws Exception {
        HttpSession sesion = ServletActionContext.getRequest().getSession();
        // Si no hay usuario en sesión, redirigir a página de login
        if(sesion.getAttribute("usuarioActual") == null){
            return "sinSesion";
        }
        return invocacion.invoke();
    }

}

Página de inicio de sesión

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Página de inicio de sesión</title>
</head>
<body>
<h1>Sistema de autenticación</h1>
<form action="Inicio_verificar">
Usuario: <input type="text" name="usuario.nombreUsuario"><br>
Contraseña: <input type="password" name="usuario.contrasena"><br>
<input type="submit" value="Iniciar sesión">
</form>

</body>
</html>

Página principal después de la verificación

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>    

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Área restringida</title>
</head>
<body>
Bienvenido: <s:property value="usuario.nombreUsuario"/>
<br>
Acceso autorizado al sistema.
</body>
</html>

Etiquetas: struts2 interceptores java web autenticación

Publicado el 6-4 03:40