Skip to content

Commit

Permalink
Merge branch 'develop-3.x' into support-3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
xaabi6 committed Jan 20, 2023
2 parents 7e388b9 + ae80059 commit d718520
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 54 deletions.
2 changes: 1 addition & 1 deletion x38ShLibClasses/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<property name="srcDir" value="./src"/>
<property name="destDir" value="./target"/>
<property name="buildDir" value="./bin"/>
<property name="version" value="3.7.1-RELEASE"/>
<property name="version" value="3.8.0-RELEASE"/>

<target name="mavenRunDependencies" description="Resuelve las dependencias del proyecto desde Maven">
<echo>${ant.home}</echo>
Expand Down
2 changes: 1 addition & 1 deletion x38ShLibClasses/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.ejie.x38</groupId>
<artifactId>x38ShLibClasses</artifactId>
<packaging>jar</packaging>
<version>3.7.1-RELEASE</version>
<version>3.8.0-RELEASE</version>
<name>x38ShLibClasses</name>
<url>http://maven.apache.org</url>
<properties>
Expand Down
2 changes: 1 addition & 1 deletion x38ShLibClasses/src/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Manifest-Version: 3.7.1-RELEASE
Manifest-Version: 3.8.0-RELEASE

165 changes: 114 additions & 51 deletions x38ShLibClasses/src/com/ejie/x38/UdaFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,108 +15,171 @@
*/
package com.ejie.x38;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.ejie.x38.serialization.ThreadSafeCache;
import com.ejie.x38.util.StackTraceManager;
import com.ejie.x38.util.ThreadStorageManager;
import com.ejie.x38.util.WrappedRequest;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
*
* Filtro principal que cumple las siguientes funciones:
* 1- Inicializa la variable de ThreadLocal que asigna un identificador a cada hilo.
* 2- Verifica si la peticion lleva la cabecera RUP, para activar el mecanismo de serializacion a traves del UdaMappingJackson2HttpMessageConverter
* 3- Si llevan excepciones no capturadas por los desarrolladores, redirige a la pagna de error
* 4- Limpia el ThreadLocal
* 2- Verifica si la petición lleva la cabecera RUP, para activar el mecanismo de serialización a través del UdaMappingJackson2HttpMessageConverter.
* 3- Si llevan excepciones no capturadas por los desarrolladores, redirige a la página de error.
* 4- Limpia el ThreadLocal.
*
* @author UDA
*
*/
public class UdaFilter extends DelegatingFilterProxy {

private static final Logger logger = LoggerFactory.getLogger(UdaFilter.class);
private static final String validationPattern = "[\\p{L}0-9\\.,\\-\\+_:~\\(\\)\\\\/¿\\?@&%#\\$\\* ]*$";

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {

HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) {
// Comprueba si ha sido referido por algún sistema de seguridad de EJIE.
final boolean refersFromSecuritySystem;
if (httpServletRequest.getHeader("referer") != null) {
// Soporta XLNetS (tanto Linux como Windows) y OAM.
refersFromSecuritySystem = Pattern.compile(
"xlnets\\.servicios(?:\\.des|\\.pru)?\\.(?:ejgv(?:\\.euskalsarea\\.eus|\\.jaso)?|jakina\\.ejie(?:des|pru)?\\.net)?"
+ "|(?:desant01\\.|pruebasnt01\\.)?jakina.ejgvdns"
+ "|sargune(?:\\.sb|\\.des|\\.pru)?\\.(?:euskadi|ejgv\\.euskalsarea)?\\.eus",
Pattern.CASE_INSENSITIVE).matcher(httpServletRequest.getHeader("referer")).find();
logger.debug("Referer is {} and the pattern result is {}", httpServletRequest.getHeader("referer"), refersFromSecuritySystem);
} else {
refersFromSecuritySystem = false;
logger.debug("Referer is null. If a value was expected, check if the protocol is still the same.");
}

HttpServletRequest httpServletRequest = (HttpServletRequest)request;

try {


logger.debug( "New request with UDA identificator "+ThreadStorageManager.getCurrentThreadId()+" has started");

String rupHeader = httpServletRequest.getHeader("RUP");
if(rupHeader!=null){
logger.debug("New request with UDA identificator {} has started", ThreadStorageManager.getCurrentThreadId());

if (httpServletRequest.getHeader("RUP") != null) {
ThreadSafeCache.addValue("RUP", "RUP");
HashMap<?, ?> map = new ObjectMapper().readValue(rupHeader, HashMap.class);
for(Entry<?, ?> entry:map.entrySet()){
ThreadSafeCache.addValue((String)entry.getKey(), (String)entry.getValue());
HashMap<?, ?> map = new ObjectMapper().readValue(httpServletRequest.getHeader("RUP"), HashMap.class);
for (Entry<?, ?> entry : map.entrySet()) {
ThreadSafeCache.addValue((String) entry.getKey(), (String) entry.getValue());
}
}

String rupMultiModelHeader = httpServletRequest.getHeader("RUP_MULTI_ENTITY");
if(rupMultiModelHeader!=null){

if (httpServletRequest.getHeader("RUP_MULTI_ENTITY") != null) {
ThreadSafeCache.addValue("RUP_MULTI_ENTITY", "RUP_MULTI_ENTITY");
}

filterChain.doFilter(request, response);
logger.debug( "Request with UDA identificator "+ThreadStorageManager.getCurrentThreadId()+" has ended");

if (!httpServletRequest.getParameterMap().isEmpty()) {
// Si se cumplen las condiciones, se procederá a validar y almacenar en sesión los parámetros recibidos.
// Esta gestión es necesaria para disponer de los datos una vez se obtenga una credencial válida a través del sistema de seguridad.
if (SecurityContextHolder.getContext().getAuthentication() == null && !refersFromSecuritySystem) {
Map<String, String[]> extraParams = new HashMap<String, String[]>();

// Validar parámetros recibidos para evitar un "Trust boundary".
for (Map.Entry<String, String[]> entry : ((Map<String, String[]>) httpServletRequest.getParameterMap()).entrySet()) {
if (entry.getValue().length > 1) {
List<String> values = new ArrayList<String>();
for (int index = 0; index < entry.getValue().length; index++) {
if (entry.getValue()[index].matches(validationPattern)) {
values.add(entry.getValue()[index]);
logger.debug("Added parameter with key {} and value {} from index {}", entry.getKey(), entry.getValue()[index], index);
} else {
logger.debug(
"Parameter with key {} and value {} in index {} does not match the pattern",
entry.getKey(), entry.getValue()[index], index);
}
}
extraParams.put(entry.getKey(), values.toArray(new String[0]));
} else {
if (entry.getValue()[0].matches(validationPattern)) {
extraParams.put(entry.getKey(), entry.getValue());
logger.debug("Added parameter with key {} and value {}", entry.getKey(), entry.getValue()[0]);
} else {
logger.debug("Parameter with key {} and value {} does not match the pattern", entry.getKey(), entry.getValue()[0]);
}
}
}

// Se guardan los parámetros en sesión para disponer de ellos una vez se obtenga la credencial.
httpServletRequest.getSession().setAttribute("REQUESTED_PARAMS", extraParams);
httpServletRequest.getSession().setAttribute("REQUEST_METHOD", httpServletRequest.getMethod());
}
}

// Cuando la sesión contenga los parámetros que se guardaron al llegar a la aplicación y el referido sea el sistema de seguridad,
// se procederá a insertar esos datos en la petición o en caso de ser una petición de tipo GET, en el query string de la misma.
if (httpServletRequest.getSession().getAttribute("REQUESTED_PARAMS") != null
&& httpServletRequest.getSession().getAttribute("REQUEST_METHOD") != null
&& !httpServletRequest.getSession().getAttribute("REQUEST_METHOD").equals("GET")
&& refersFromSecuritySystem) {
logger.debug(
"Request will be wrapped using WrappedRequest because both REQUESTED_PARAMS and REQUEST_METHOD (with {} value) exist in session",
httpServletRequest.getSession().getAttribute("REQUEST_METHOD"));
filterChain.doFilter(
new WrappedRequest(httpServletRequest,
(Map<String, String[]>) httpServletRequest.getSession().getAttribute("REQUESTED_PARAMS"),
httpServletRequest.getSession().getAttribute("REQUEST_METHOD").toString()),
response);
} else {
logger.debug("Request won't be wrapped");
filterChain.doFilter(request, response);
}

logger.debug("Request with UDA identificator {} has ended", ThreadStorageManager.getCurrentThreadId());
} catch (Exception exception) {
logger.error(StackTraceManager.getStackTrace(exception));

// HttpSession session = httpServletRequest.getSession();
// String sessionId = httpServletRequest.getSession().getId();

try {

if (!response.isCommitted()){
// ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
// StockUdaSecurityPadlocksImpl stockUdaSecurityPadlocks = (StockUdaSecurityPadlocksImpl)ctx.getBean("stockUdaSecurityPadlocks");
// if (stockUdaSecurityPadlocks != null && stockUdaSecurityPadlocks.existingSecurityPadlock(sessionId)){
// stockUdaSecurityPadlocks.setAllowedAccessThread(sessionId, null);
// stockUdaSecurityPadlocks.release(sessionId);
// }

HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;

StringBuilder error = new StringBuilder(req.getContextPath());
if (!response.isCommitted()) {
StringBuilder error = new StringBuilder(httpServletRequest.getContextPath());
error.append("/error?exception_name=").append(exception.getClass().getName());
error.append("&exception_message=").append(exception.getMessage());
error.append("&exception_trace=");
int outLength = error.length();

for (StackTraceElement trace : exception.getStackTrace()) {
outLength = outLength + 5 /* </br> */ + trace.toString().length();
if (outLength <= 2043 /* IE Query String limit */){
outLength = outLength + 5 + trace.toString().length();
// IE Query String limit
if (outLength <= 2043) {
error.append(trace.toString()).append("</br>");
} else {
break;
}
}
res.sendRedirect(error.toString());

httpServletResponse.sendRedirect(error.toString());
}
} catch (Exception exc) {
logger.error("Problem with sending of the response",exc);
} catch (Exception exc) {
logger.error("Problem with sending of the response", exc);
}
}finally{
} finally {
ThreadStorageManager.clearCurrentThreadId();
ThreadSafeCache.clearCurrentThreadCache();

// Eliminar los parámetros que se hayan podido ingresar en la sesión antes de la obtención de una credencial.
if (refersFromSecuritySystem) {
httpServletRequest.getSession().removeAttribute("REQUESTED_PARAMS");
httpServletRequest.getSession().removeAttribute("REQUEST_METHOD");
}
}
}
}
97 changes: 97 additions & 0 deletions x38ShLibClasses/src/com/ejie/x38/util/WrappedRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2022 E.J.I.E., S.A.
*
* Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en
*
* https://ec.europa.eu/idabc/eupl.html
*
* Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,
* el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,
* SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.
* Véase la Licencia en el idioma concreto que rige los permisos y limitaciones
* que establece la Licencia.
*/
package com.ejie.x38.util;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class WrappedRequest extends HttpServletRequestWrapper {
private final String requestMethod;
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;

/**
* Crea una envoltura sobre la petición que permite incluir parámetros
* adicionales en el objeto de petición. No lee prematuramente los parámetros de
* la petición original.
*
* @param request Petición original.
* @param additionalParams Parámetros adicionales a ingresar en la petición.
*/
public WrappedRequest(final HttpServletRequest request, final Map<String, String[]> additionalParams) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
requestMethod = ((HttpServletRequest) super.getRequest()).getMethod();
}

/**
* Crea una envoltura sobre la petición que permite incluir parámetros
* adicionales en el objeto de petición además de modificar el método. No lee
* prematuramente los parámetros de la petición original.
*
* @param request Petición original.
* @param additionalParams Parámetros adicionales a ingresar en la petición.
* @param method Método a definir en la petición.
*/
public WrappedRequest(final HttpServletRequest request, final Map<String, String[]> additionalParams, final String method) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
requestMethod = method;
}

@Override
public String getParameter(final String name) {
String[] strings = getParameterMap().get(name);
if (strings != null) {
return strings[0];
}
return super.getParameter(name);
}

@Override
@SuppressWarnings("unchecked")
public Map<String, String[]> getParameterMap() {
if (allParameters == null) {
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
// Devuelve una colección no modificable porque se debe mantener el contrato.
return Collections.unmodifiableMap(allParameters);
}

@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}

@Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}

@Override
public String getMethod() {
return requestMethod;
}
}

0 comments on commit d718520

Please sign in to comment.