Buscar este blog

viernes, 29 de abril de 2016

Maven - Log4j2 with slf4j

How to use log4j2 logging over the simple log facade (slf4j).

pom.xml
<dependencies>

  <dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-slf4j-impl</artifactId>
   <version>2.5</version>
  </dependency>



  <dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-api</artifactId>
   <version>2.5</version>
  </dependency>

  <dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-core</artifactId>
   <version>2.5</version>
  </dependency>
  
 </dependencies>


You need to configure de log4j2 impl, for example, by using a log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
 <Appenders>
  <Console name="CONSOLE" target="SYSTEM_OUT">
   <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
  </Console>

  <RollingFile name="FILE" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz" ignoreExceptions="false">
   <PatternLayout>
    <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
   </PatternLayout>
   <TimeBasedTriggeringPolicy />
  </RollingFile>
 </Appenders>
 
 
 <Loggers>
  
  <Logger name="com.foo.Bar" level="trace" additivity="false">
      <AppenderRef ref="CONSOLE" />
   <AppenderRef ref="FILE" />
    </Logger>
 
  <Root level="INFO">
   <AppenderRef ref="CONSOLE" />
   <AppenderRef ref="FILE" />
  </Root>
 </Loggers>
</Configuration>

domingo, 24 de abril de 2016

@Firma - Firma trifase con Autofirma 1.4.2

Según se indica en su página oficial, @firma es una plataforma de validación y firma electrónica multi-PKI desarrollada por el MINHAP, y que se pone a disposición de las Administraciones Públicas, proporcionando servicios para implementar la autenticación y firma electrónica avanzada de una forma rápida y efectiva.

Originariamente @firma sólo ofrecía un applet de firma para hacer firma en cliente. De este modo las aplicaciones incluían una serie de librerías y javascript en sus páginas para ejecutar el este applet, que era el que se encargaba de acceder a los certificados del usuario.

Con la progresiva caída en desuso de los applets se ha potenciado el uso de un componente de usuario denominado Autofirma. Se trata de una aplicación independiente que debe instalar manualmente el usuario y que es quien en última instancia realiza la firma.

El caso más básico de funcionamiento consiste en que desde la página web se invoque el componente de autofirma pasándole el fichero que se desea firmar (en base 64), se firme en local, y luego se envíe de vuelta a la página. De ahí, volvería finalmente al servidor.

Este modelo de integración es válido cuando los ficheros son relativamente pequeños, pero para documentos mayores implica un tráfico de red excesivo. Además, en algunos dispositivos móviles no se permite la descarga de documentos, como por ejemplo en iOS.

Para solventar estos problemas se dispone de la opción de firma trifase. En estos casos, el documento nunca llega a salir del servidor remoto y la firma se realiza de forma conjunta entre autofirma y una nueva aplicación web denominada servidor trifase.

Cuando desde página web se invoca a autofirma (a través de invocación por protocolo), se le pasa como parámetro la URL del servidor trifase y un identificador que hace referencia al fichero remoto que se quiere firmar. Autofirma establece una comunicación con el servidor trifase, indicándole este identificador y se intercambian mensajes para componer una firma e incrustrarla en en el documento resultante.

En la siguiente imagen se muestra el diagrama general de funcionamiento.


El componente autofirma y el server trifase se pueden descargar de la página de la forma del CTT, http://forja-ctt.administracionelectronica.gob.es/web/clienteafirma. Desde ahí se puede ir a la página de la forja.

Además, el código fuente del server trifase (como el del resto del proyecto) se puede consultar en su github https://github.com/ctt-gob-es/clienteafirma.

Para hacer pruebas lo mejor es descargar el server trifase y modificar su config.properties para que emplee acceda a una ruta de disco, que servirá de entrada y salida de los ficheros firmados. El fichero de configuración está en WEB-INF/classes/config.properties:
# Origenes permitidos
Access-Control-Allow-Origin=*

# Clase DocumentManager
#document.manager=es.gob.afirma.triphase.server.document.SelfishDocumentManager
document.manager=es.gob.afirma.triphase.server.document.FileSystemDocumentManager

# Instalar provedor de XMLdSig alternativo
alternative.xmldsig=false

# Configuracion de la clase FileSystemDocumentManager
indir=D:/tmp/afirma/entrada
outdir=D:/tmp/afirma/salida
overwrite=true

Luego basta con desplegarlo tal cual en un servidor de aplicaciones, por ejemplo tomcat.

Al descargar el componente de autofirma también se incluye una página para probar todas las opciones disponibles de firma. He cogido esa página y la he recortado para dejar únicamente la parte de firma trifase.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <!-- Ejemplo basico de lanzador de la aplicacion -->
  <head>
 <title>Ejemplo de despliegue del MiniApplet @firma</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
 <script type="text/javascript" src="miniapplet.js"></script>
 <script type="text/javascript">

  function doSign() {
   try {
    MiniApplet.sign(
     document.getElementById("idFicheroServidor").value,
     "SHA512withRSA",
     "PAdEStri",
     document.getElementById("params").value,
     showResultCallback,
     showErrorCallback);
    
   } catch(e) {
    try {
     showLog("Type: " + MiniApplet.getErrorType() + "\nMessage: " + MiniApplet.getErrorMessage());
    } catch(ex) {
     showLog("Error: " + e);
    }
   }
  }
  
  function showResultCallback(signatureB64, certificateB64) {
   showLog("Firma OK");
   document.getElementById('result').value = signatureB64;
   document.getElementById('certificate').value = certificateB64;
  }
 
  function showErrorCallback(errorType, errorMessage) {
   showLog("Type: " + errorType + "\nMessage: " + errorMessage);
  }
    
  function showAppletLog() {
   try {
    showLog(MiniApplet.getCurrentLog());
   } catch(e) {
    showLog("Type: " + MiniApplet.getErrorType() + "\nMessage: " + MiniApplet.getErrorMessage());
   }
  }
  
  function cleanDataField(dataField, textDiv) {
   textDiv.innerHTML = "";
   dataField.value = null;
  }
  
  function addExtraParam(extraParam) {
   var paramsList = document.getElementById("params");
   paramsList.value = paramsList.value + extraParam + "\n";
   document.getElementById('newParam').value = "";
  }
  
  function cleanExtraParams() {
   document.getElementById("params").value = "";
   document.getElementById('newParam').value = "";
  }
  
  function showLog(newLog) {
   document.getElementById('console').value = document.getElementById('console').value + "\n" + newLog;
  }
 </script>
  </head>
 <body>
  <script type="text/javascript">
   MiniApplet.setForceWSMode(false);
   MiniApplet.cargarAppAfirma();
  </script>

  
  <fieldset><legend>Entrada de datos</legend>
  <div>
    <span>Identificador de fichero en servidor:</span> <input id="idFicheroServidor" type="text" value="prueba.pdf">      
  </div>
  </fieldset>
  <br/>
  
  <fieldset><legend>Configuraci&oacute;n de la firma</legend>  
   <div>
     <label for="newParam">ExtraParams</label>
     <input id="newParam" type="text"><input type="button" value="Agregar" onclick="addExtraParam(document.getElementById('newParam').value);">&nbsp;
     <input type="button" value="Limpiar" onclick="cleanExtraParams();">&nbsp;
     <span>(Insertar las propiedades de una en una)</span>
     <br>
    <textarea id="params" cols="50" rows="5" readonly>serverUrl=http://localhost:8080/afirma-server-triphase-signer/SignatureService
    </textarea>
   </div>
  </fieldset>
  <br/>

  <input type="button" value="Firmar" onclick="doSign();">&nbsp;  
  <input type="button" value="Mostrar Log" onclick="showAppletLog();">
  <br/>
  
  <div>
   <span>Consola</span>
   <br>
   <textarea id="console" cols="150" rows="10">
   </textarea>
  </div>
  
  <div>
   <span>Resultado</span>
   <br>
   <textarea id="result" cols="150" rows="10">
   </textarea>
  </div>
  
  <div>
   <span>Certificado</span>
   <br>
   <textarea id="certificate" cols="150" rows="10">
   </textarea>
  </div>
 </body>
</html>

Esta página invoca la firma trifase de tipo PAdES (firma de PDF).


El único parámetro que hay que cubrir es el identificador del fichero, que será el nombre de un fichero que se encuentre en el directorio de entrada configurado dentro del server trifase.

Para ver los mensajes intercambiados entre autofirma y el server trifase se puede utilizar un filtro de log de tomcat como el describía en una entrada anterior http://trabajosdesisifo.blogspot.com.es/2016/03/tomcat-custom-request-dump-filter-log.html

sábado, 2 de abril de 2016

Camel - CXF - Spring Boot - Web Service proxy Camel Route

This is a simple Spring Boot application, based on Apache Camel which act as a web service proxy. It is useful when you want to make accessible a web service allocated in a non accessible network. You can deploy it in an intermediate machine accessible from both sides.

This is a project based on this post in Java Code Geeks, but making it bootiful ;).

The project is very simple, you only need one Camel Route:
@Configuration
public class CamelConfig {

 @Bean
 public RouteBuilder routeBuilder() {
  return new RouteBuilder() {
   @Override
   public void configure() throws Exception {
    from("cxf:bean:servicePublisher?dataFormat=POJO")
    .log(LoggingLevel.INFO,"Doing some stuff")
    .to("cxf:bean:serviceConsumer?dataFormat=POJO");
   }
  };
 }
}

The route uses two CXF Endpoints, by publishing and by consuming the same web service contract.
This is the CXF config:
@Configuration
@ImportResource("classpath:/spring/conduit-config.xml")
public class CxfConfig {

 @Value("${service.publish.localEndpoint}")
 private String localEndPoint;

 @Value("${service.client.remoteEndpoint}")
 private String remoteEndPoint;


 @Bean
 public LoggingInInterceptor loggingInInterceptor() {
  final LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor();
  loggingInInterceptor.setPrettyLogging(true);
  return loggingInInterceptor;
 }


 @Bean
 public LoggingOutInterceptor loggingOutInterceptor() {
  final LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
  loggingOutInterceptor.setPrettyLogging(true);
  return loggingOutInterceptor;
 }


 @Bean
 public GZIPInInterceptor gzipInInterceptor() {
  return new GZIPInInterceptor();
 }


 @Bean
 public CxfEndpoint servicePublisher(final CamelContext camelContext) {
   final CxfComponent cxfComponent = new CxfComponent(camelContext);

   final CxfEndpoint serviceEndpoint = new CxfEndpoint("", cxfComponent);
   serviceEndpoint.setServiceClass(ProductPortImpl.class);
   serviceEndpoint.setAddress(localEndPoint);
   serviceEndpoint.setWsdlURL("/wsdl/service/productService.wsdl");

   serviceEndpoint.setServiceNameString("{http://ws.javacodegeeks.com/product-service}ProductService");
   serviceEndpoint.setEndpointNameString("ProductPort");

   serviceEndpoint.setDataFormat(DataFormat.POJO);

   serviceEndpoint.setLoggingFeatureEnabled(true);
   serviceEndpoint.getInInterceptors().add(gzipInInterceptor());
   serviceEndpoint.getInInterceptors().add(loggingInInterceptor());
   serviceEndpoint.getOutInterceptors().add(loggingOutInterceptor());

   return serviceEndpoint;
 }


 @Bean
 public CxfEndpoint serviceConsumer(final CamelContext camelContext) {
   final CxfComponent cxfComponent = new CxfComponent(camelContext);

   final CxfEndpoint serviceEndpoint = new CxfEndpoint("", cxfComponent);
   serviceEndpoint.setServiceClass(Product.class);
   serviceEndpoint.setAddress(remoteEndPoint);
   serviceEndpoint.setWsdlURL("/wsdl/service/productService.wsdl");

   serviceEndpoint.setServiceNameString("{http://ws.javacodegeeks.com/product-service}ProductService");
   serviceEndpoint.setEndpointNameString("ProductPort");

   serviceEndpoint.setDataFormat(DataFormat.POJO);

   serviceEndpoint.setLoggingFeatureEnabled(true);
   serviceEndpoint.getInInterceptors().add(gzipInInterceptor());
   serviceEndpoint.getInInterceptors().add(loggingInInterceptor());
   serviceEndpoint.getOutInterceptors().add(loggingOutInterceptor());

   return serviceEndpoint;
 }
}

The end points configuration is very similar, but there is two differences:
  • The publisher service class references the service impl class. The consumer service class references the service interface class.
  • The publisher  service address references the full URL in which this project will publish the service. The consumer service address references the full URL in which the true service is published (by a third app)

You also need to keep in mind the SSL, so you need a http conduit for the client end point. I tried to configure it with java-based configuration, but I couldn't, so I finally  opted for XML-based configuration.
This is the conduit-config.xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:cxf="http://camel.apache.org/schema/cxf"
 xmlns:sec="http://cxf.apache.org/configuration/security" 
 xmlns:http="http://cxf.apache.org/transports/http/configuration"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
              http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
              http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
              http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
              http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">

 
 <http:conduit name="{http://ws.javacodegeeks.com/product-service}ProductPort.http-conduit">
     <http:client Accept="text/xml" AcceptEncoding="gzip,deflate,sdch"  AllowChunking="true" AutoRedirect="true" CacheControl="No-Cache" ContentType="text/xml"/>
     
  <http:tlsClientParameters disableCNCheck="true">
   <sec:trustManagers>
    <sec:keyStore file="${service.client.truststore.path}" type="jks" password="${service.client.truststore.pass}" />
   </sec:trustManagers>
  </http:tlsClientParameters>
 </http:conduit>
  
</beans>

Some configuration values are environment-dependant, so I used a external properties file. This file also references a truststore used by the conduit config.
This is the PropertiesConfig file:
@Configuration
@PropertySources({
 @PropertySource("classpath:conf.properties"),
 @PropertySource("file:${propertyFile}")
})
public class PropertiesConfig {
 @Bean
 public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

When you launch the project, you need to pass it the propertyFile key, for example as a command line argument.

The full source code is in my githubhttps://github.com/evazquezma/JEE6/tree/master/proxy-service

viernes, 25 de marzo de 2016

Java servlet download log file

This is a basic servlet to download the log files of  a web app.
The servlet has the following config params:
  • logsConfigLocation. The base dir in which the log files are stored. It is not allowed to read files outside this directory.
  • logsMaxSize. The maximum size of the log file allowed to download
The config params can be configured usen Spring Expression Language, so a valid value could be ${my.config.property:/home/jboss/logs}
If none is specified, the default values are jboss.server.log.dir and 10MB respectively.


In order to prevent public access to this files, the servlet can be configured to use basic authentication. In this case, you need to configure the appropriate login mechanism in the app, form example, in web.xml:
<login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>default</realm-name>
</login-config>

The servlet receives a request param called "path" which contains the relative route of the requested log file.

LoggerServlet:
package es.sisifo.jee6.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.util.ServletContextPropertyUtils;


@WebServlet(urlPatterns = { "/loggerServlet" })
@ServletSecurity(@HttpConstraint(rolesAllowed = { "admin" }))
public class LoggerServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public static final String CONFIG_LOCATION_PARAM = "logsConfigLocation";
    public static final String CONFIG_MAXSIXE_PARAM = "logsMaxSize";

    private String logsLocation = System.getProperty("jboss.server.log.dir");
    private int maxFileSize = 10485760; // 10MB

    @Override
    public void init(final ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);

        if (servletConfig.getInitParameter(CONFIG_LOCATION_PARAM) != null) {
            logsLocation = ServletContextPropertyUtils.resolvePlaceholders(
                    servletConfig.getInitParameter(CONFIG_LOCATION_PARAM), servletConfig.getServletContext());
        }

        if (servletConfig.getInitParameter(CONFIG_MAXSIXE_PARAM) != null) {
            maxFileSize = Integer.valueOf(ServletContextPropertyUtils.resolvePlaceholders(
                    servletConfig.getInitParameter(CONFIG_MAXSIXE_PARAM), servletConfig.getServletContext()));
        }
    }


    @Override
    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException,
            IOException {

        final String path = request.getParameter("path");
        if (!isValidPath(path)) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid path");
            return;
        }

        final File logFile = new File(logsLocation + File.separator + path);
        if (!isValidFile(logFile)) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid file");
            return;
        }

        downloadFile(logFile, response);
    }


    private void downloadFile(final File logFile, final HttpServletResponse response) throws IOException {
        final FileInputStream inStream = new FileInputStream(logFile);

        response.setContentType(getServletContext().getMimeType(logFile.getAbsolutePath()));
        response.setContentLength((int) logFile.length());
        response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", logFile.getName()));


        final OutputStream outStream = response.getOutputStream();

        final byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, bytesRead);
        }

        inStream.close();
        outStream.close();
    }


    private boolean isValidPath(final String path) {
        return path != null && !path.contains("..");
    }


    private boolean isValidFile(final File logFile) {
        return logFile.exists() && logFile.isFile() && logFile.length() <= maxFileSize;
    }
}

domingo, 13 de marzo de 2016

Tomcat - Custom request dump filter - Log request and response body

Tomcat 7 has two components to intercept server requests:
Both are almost the same, with the difference that valves are tomcat specific.
In previous versions, tomcat had a valve to log http traffic, but in the last releases it was eliminated and substituted by a filter called Request_Dumper_Filter (https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Request_Dumper_Filter).
You can configure this filter in tomcat server.xml, so it will intercept all requests for all the applications hosted by the server (well, you can specify a URL pattern). In this way, if you want to monitor a concrete app, you dont need to change it, just reconfigure tomcat.

The problem with Request_Dumper_Filter is that it does not work properly with application/x-www-form-urlencoded POST requests. So it may make the back-end servlets to fail, because when you read the request parameters, you are consuming its input stream.

The solution is to create a custom Dumper Filter to solve this. I found two interesting partial implementations here and here, based in request and response wrappers, and unify them in a single filter.

The code is in https://github.com/evazquezma/tomcat/tree/master/custom-tomcat-utils.

In order to use this filter you need to do as follows:
1) Copy the jar to the ${CATALINA_HOME}/lib

2) Edit ${CATALINA_HOME}/conf/server.xml and declare the filter:
<filter>
 <filter-name>requestdumper</filter-name>
 <filter-class>es.sisifo.tomcatutil.filters.SimpleRequestDumperFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>requestdumper</filter-name>
 <url-pattern>*</url-pattern>
</filter-mapping>

3) Edit ${CATALINA_HOME}/conf/loggin.properties and configure the traces:
handlers = (...), 5request-dumper.org.apache.juli.FileHandler
(....)
5request-dumper.org.apache.juli.FileHandler.level = INFO
5request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
5request-dumper.org.apache.juli.FileHandler.prefix = request-dumper.
5request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter
es.sisifo.tomcatutil.filters.SimpleRequestDumperFilter.level = INFO
es.sisifo.tomcatutil.filters.SimpleRequestDumperFilter.handlers = \
5request-dumper.org.apache.juli.FileHandler

The result will be something like this (this is a log from this app):
http-bio-8080-exec-4 ******************=********************************************
http-bio-8080-exec-4 START TIME       a =13-mar-2016 12:07:02
http-bio-8080-exec-4         requestURI=/afirma-server-triphase-signer/SignatureService
http-bio-8080-exec-4           authType=null
http-bio-8080-exec-4  characterEncoding=null
http-bio-8080-exec-4      contentLength=2259
http-bio-8080-exec-4        contentType=application/x-www-form-urlencoded
http-bio-8080-exec-4        contextPath=/afirma-server-triphase-signer
http-bio-8080-exec-4             header=accept=*/*
http-bio-8080-exec-4             header=content-type=application/x-www-form-urlencoded
http-bio-8080-exec-4             header=user-agent=Java/1.8.0_60
http-bio-8080-exec-4             header=host=localhost:8080
http-bio-8080-exec-4             header=connection=keep-alive
http-bio-8080-exec-4             header=content-length=2259
http-bio-8080-exec-4             locale=es_ES
http-bio-8080-exec-4             method=POST
http-bio-8080-exec-4          parameter=op=pre
http-bio-8080-exec-4          parameter=cop=sign
http-bio-8080-exec-4          parameter=format=pades
http-bio-8080-exec-4          parameter=algo=SHA512withRSA
http-bio-8080-exec-4          parameter=cert=MIIC6jCCAdKgAwIBAgIEVtGLlDANBgkqhkiG9w0BAQsFADA9MRswGQYDVQQLDBJKYm9zcyBBcnF1aXRlY3R1cmExHjAcBgNVBAMMFUNBLUpCT1NTIEFycXVpdGVjdHVyYTAgFw0xNjAyMjcxMTQyMzNaGA8yMTE1MDIyNzExNDIzM1owLzENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDEPMA0GA1UEAwwGc2lzaWZvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6GJwUNgmPFoE48U-8CU2jdTPRTl-GthiGyk7ggo-V3MYMgQ_7imW7WzAm7rGVncwtJ_-JYiHSG-Kry1Fb558ux2_9yLY6cfOvQroid9kpH2lRoZ-pBBl1Ww7GO3Z0FZKVf0TJIIDSv__NuPFIV0IxEYezWWDCW9NfzKqjrkbdNgJB07T8M7cWUuojW8LcbV_i3Z-m0pLif51cbdyLjowtbqKN_b04tP74PjQt5hI9tmBRIL51bRebAn6xc2C34_fiIf9AEETpRV_YLh80eClueeb4qiiaSWkYwo11FCswZE0eHSBTpwYrHX1IWMdZ64-IUYAwSvz4Ypx0Ma_JEiFJQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBtI5LSsXlCK4u3PRjYXdD-lruCEIpw1YNow9SYIe_zyg_W060R0Ir-Xr3wEt6Buf1vjfOSg5J1hF3xxoRt-Dvj1La6xWNnYiF8g2mozNFs-FeL8m1Tv7Ll8LKShmOyJXDzkEpBcK4eZp92mgBH2JuOF8emhrP6BJqb2C4fR6KL3um4OlgIynGWYcdZvXcUt3k5rU6QShrCNxpfraPzeGzDifG2zmSI4GraoB7FwTiMLDjg8_20kmxot_w5Tm31D79F-XL2_qfP9TQL_qhV7F-5WR-bMSU1oa3hI0rJYvRuNF8KsPEaRUoLvRpEpW8dJ-XEgUL9etVAuSEk3obPFzJF,MIIC-DCCAeCgAwIBAgIEVMp9_TANBgkqhkiG9w0BAQsFADA9MRswGQYDVQQLDBJKYm9zcyBBcnF1aXRlY3R1cmExHjAcBgNVBAMMFUNBLUpCT1NTIEFycXVpdGVjdHVyYTAgFw0xNTAxMjkxODM4MTFaGA8yMTE0MDEyOTE4MzgxMVowPTEbMBkGA1UECwwSSmJvc3MgQXJxdWl0ZWN0dXJhMR4wHAYDVQQDDBVDQS1KQk9TUyBBcnF1aXRlY3R1cmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCBnpiP835iOWmqrDdgBWyp8yaG6pe_PVI944YqU_AKlrsa_WZFxMRy6Uri0TGuT5hlmUJsw6e7fDR9bf7F4K5wE4ZSEVG_njlDShjlsJ4CgvVfneK-kOva9KzlpUM3do-Bm-3WbfvHl0d8eujc_sHD4uSyH1yI04r9YrHN0OeY1qFfsowS3EzPdTsw9oeoBAyW4nVZQG-VqXwBSnkwxQOEERN_-3l9tSxEV12gRDieUJj5y3USdfxHruqNPbmAu6yc2rXIR7yeeq0CCrbnvTlW81lCVWvSVV2o9fFt-irdP4P20e-ecR-24VzIV7Brm4LE3snmExDb-aLF6XmqiokTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAcsXzdYsrAnUwd269PMUNa4cSBnDk7g9YY36KHIDLo72XTJOgbeb-pQXWEwr5A5vuH1MeT_CHYMJkPvqM4kaFVN4zQVOhi3XKzTSAsLCERprvwU0bg2Nk65TeE6SIELWfWkcdko8x3Hn0uwEniJXA275G_kT15aBQ1tiyEGhYwPpO3pdKeMRmtFZfyvuernVAko9-FCBauH7KFZGIpne-VzA2rIFa0kTta1HesVeoAmetltgvxGdNrwnQJZfg8PNTF3ceQSyK0quCJv4nxcy_pwV-tQRXXLScvIFRuXdu6782PSDFa17TYY9FOPmyMKiwsz-yjCu8JB9xuPCrzRnuE=
http-bio-8080-exec-4          parameter=doc=cHJ1ZWJhLnBkZg==
http-bio-8080-exec-4          parameter=params=Iw0KI1N1biBNYXIgMTMgMTI6MDc6MDIgQ0VUIDIwMTYNCnNlcnZlclVybD1odHRwXDovL2xvY2FsaG9zdFw6ODA4MC9hZmlybWEtc2VydmVyLXRyaXBoYXNlLXNpZ25lci9TaWduYXR1cmVTZXJ2aWNlDQo=
http-bio-8080-exec-4           pathInfo=null
http-bio-8080-exec-4           protocol=HTTP/1.1
http-bio-8080-exec-4        queryString=null
http-bio-8080-exec-4         remoteAddr=127.0.0.1
http-bio-8080-exec-4         remoteHost=127.0.0.1
http-bio-8080-exec-4         remoteUser=null
http-bio-8080-exec-4 requestedSessionId=null
http-bio-8080-exec-4             scheme=http
http-bio-8080-exec-4         serverName=localhost
http-bio-8080-exec-4         serverPort=8080
http-bio-8080-exec-4        servletPath=/SignatureService
http-bio-8080-exec-4           isSecure=false
http-bio-8080-exec-4           authType=null
http-bio-8080-exec-4         remoteUser=null
http-bio-8080-exec-4 ------------------=--------------------------------------------
http-bio-8080-exec-4 ------------------=--------------------------------------------
http-bio-8080-exec-4        contentType=text/plain;charset=utf-8
http-bio-8080-exec-4             header=Access-Control-Allow-Origin=*
http-bio-8080-exec-4             status=200
http-bio-8080-exec-4 Response body=PHhtbD4KIDxmaXJtYXM-CiAgPGZpcm1hIElkPSI5MzQ2YTllYi00NDNlLTRhYjAtODVhZC03ODE1YjViMjFhM2IiPgogICA8cGFyYW0gbj0iTkVFRF9QUkUiPnRydWU8L3BhcmFtPgogICA8cGFyYW0gbj0iVElNRSI-MTQ1Nzg2NzIyMjY3ODwvcGFyYW0-CiAgIDxwYXJhbSBuPSJQUkUiPk1ZSUJJekFZQmdrcWhraUc5dzBCQ1FNeEN3WUpLb1pJaHZjTkFRY0JNRThHQ1NxR1NJYjNEUUVKQkRGQ0JFQk1NdHpSTTNIV3F0R1NEYWlBQjBHalFKNTd0dXh3bGVIV2pBcmhTV2ViRVltd0dFcFpyYjFndGIwSUZKbGhmMmVITmkzYnpKVUlzMHBTSFg0OHhFVU5NSUcxQmdzcWhraUc5dzBCQ1JBQ0x6R0JwVENCb2pDQm56Q0JuREFOQmdsZ2hrZ0JaUU1FQWdNRkFBUkEvRWNydW1KSFhzaSt5Y2xZa05WODNlQ0RUWWZLM3VuTkhHeEpTdmRaanBwR1RIVW5lUkpmLyszVW9yV3FZdlZGelJzMkNORGlsQTFTVnVFOHN3dEtWREJKTUVHa1B6QTlNUnN3R1FZRFZRUUxEQkpLWW05emN5QkJjbkYxYVhSbFkzUjFjbUV4SGpBY0JnTlZCQU1NRlVOQkxVcENUMU5USUVGeWNYVnBkR1ZqZEhWeVlRSUVWdEdMbEE9PTwvcGFyYW0-CiAgIDxwYXJhbSBuPSJQSUQiPld6eGhPREpqWVdVMU1qZGtaR015WW1SalpURmpNR1JpTXpneU5EUTROakkxTXo0OE4yTTRNemxqT0RobE9EaGhZakU0TURKallqTm1PRE14TWpneE5XTmtOR0krWFE9PTwvcGFyYW0-CiAgPC9maXJtYT4KIDwvZmlybWFzPgo8L3htbD4=
http-bio-8080-exec-4 END TIME          =13-mar-2016 12:07:02
http-bio-8080-exec-4 ===============================================================