En la anterior entrada dejamos montado un ejemplo con Apache CFX y WS-Security. Pero como Apache CXF utiliza por defecto slf4j el lugar de log4j, teníamos el log de las peticiones y respuestas en ficheros distintos al resto de los módulos, donde usamos log4j.
Vamos a repasar como ajustar ambos módulos para que se genere la traza en nuestro fichero de log habitual.
Aplicativo cxf-web
1) Deberemos ajustar el fichero /src/main/resources/log4j.properties con el siguiente contenido:
log4j.rootCategory=INFO,CONSOLA
log4j.logger.es.ine.cxf.ws=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingInInterceptor.level=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingOutInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JInInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JOutInterceptor.level=INFO
log4j.appender.CONSOLA=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLA.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLA.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.FICHERO=org.apache.log4j.RollingFileAppender
log4j.appender.FICHERO.file=${log4j.debug.ruta_fichero}/cxf-web.log
log4j.appender.FICHERO.append=true
log4j.appender.FICHERO.MaxFileSize=${log4j.debug.MaxFileSize}
log4j.appender.FICHERO.MaxBackupIndex=${log4j.debug.MaxBackupIndex}
log4j.appender.FICHERO.layout=org.apache.log4j.PatternLayout
log4j.appender.FICHERO.layout.ConversionPattern=[%d{dd-MM-yyyy HH\:mm\:ss,SSS}] thread\:[%t] nivelTraza\:[%p] lugarTraza\:[%c] mensajeTraza[%m]%n
2) Deberemos crear un fichero llamado:
/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
El contenido de este fichero será:
org.apache.cxf.common.logging.Log4jLogger
3) Deberemos ajustar nuestra clase cliente así:
package es.ins.sgtic.app;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import es.ine.cxf.ws.impl.Calculadora;
import es.ine.cxf.ws.impl.CalculadoraImplService;
public class AppTest {
private static final QName SERVICE_NAME = new QName("http://impl.ws.cxf.ine.es/", "CalculadoraImplService");
public static void main(String[] args) {
//Definimos el servicio web a usar
final URL wsdlURL = CalculadoraImplService.WSDL_LOCATION;
final CalculadoraImplService calcService = new CalculadoraImplService(wsdlURL, SERVICE_NAME);
final Calculadora calculadora = calcService.getCalculadoraImplPort();
//Obtenemos la referencia al endpoint del ws
final Client client = ClientProxy.getClient(calculadora);
final Endpoint cxfEndpoint = client.getEndpoint();
//Ajustamos el log del cliente
final LoggingInInterceptor incerceptorLogIn = new LoggingInInterceptor();
incerceptorLogIn.setPrettyLogging(true);
final LoggingOutInterceptor incerceptorLogOut = new LoggingOutInterceptor();
incerceptorLogOut.setPrettyLogging(true);
client.getInInterceptors().add(incerceptorLogIn);
client.getOutInterceptors().add(incerceptorLogOut);
//Configuramos el interceptor de cifrado/firmado para los envíos
final Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put("action", "Timestamp Signature Encrypt");
outProps.put("user", "edugarci");
outProps.put("signaturePropFile", "props/client-key-store.properties");
outProps.put("signatureKeyIdentifier", "DirectReference");
outProps.put("passwordCallbackClass", "es.ine.cxf.ws.sec.PasswordCallback");
outProps.put("signatureParts", "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionPropFile", "props/client-trust-store.properties");
outProps.put("encryptionUser", "desarrollo-internet");
outProps.put("encryptionParts", "{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); //request
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor());
//Configuramos el interceptor de descifrado/verificacion-firma para las recepciones
Map<String,Object> inProps= new HashMap<String,Object>();
inProps.put("action", "Timestamp Signature Encrypt");
inProps.put("signaturePropFile", "props/client-trust-store.properties");
inProps.put("passwordCallbackClass", "es.ine.cxf.ws.sec.PasswordCallback");
inProps.put("decryptionPropFile", "props/client-key-store.properties");
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); //response
cxfEndpoint.getInInterceptors().add(wssIn);
cxfEndpoint.getInInterceptors().add(new SAAJInInterceptor());
//Lanzamos unas peticiones de ejemplo
System.out.println(String.format("port.suma(15, 3) --> %d",calculadora.suma(15, 3)));
System.out.println(String.format("port.resta(15, 3) --> %d",calculadora.resta(15, 3)));
System.out.println(String.format("port.multiplica(15, 3) --> %d",calculadora.multiplica(15, 3)));
System.out.println(String.format("port.divide(15, 3) --> %d",calculadora.divide(15, 3)));
}
}
Aplicativocxf-client
1) Deberemos ajustar el fichero /src/main/resources/log4j.properties con el siguiente contenido:
log4j.rootCategory=INFO,CONSOLA
log4j.logger.es.ine.cxf.ws=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingInInterceptor.level=INFO
log4j.logger.org.apache.cxf.interceptor.LoggingOutInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JInInterceptor.level=INFO
log4j.logger.org.apache.cxf.ws.rm.security.wss4j.WSS4JOutInterceptor.level=INFO
log4j.appender.CONSOLA=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLA.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLA.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.FICHERO=org.apache.log4j.RollingFileAppender
log4j.appender.FICHERO.file=${log4j.debug.ruta_fichero}/cxf-web.log
log4j.appender.FICHERO.append=true
log4j.appender.FICHERO.MaxFileSize=${log4j.debug.MaxFileSize}
log4j.appender.FICHERO.MaxBackupIndex=${log4j.debug.MaxBackupIndex}
log4j.appender.FICHERO.layout=org.apache.log4j.PatternLayout
log4j.appender.FICHERO.layout.ConversionPattern=[%d{dd-MM-yyyy HH\:mm\:ss,SSS}] thread\:[%t] nivelTraza\:[%p] lugarTraza\:[%c] mensajeTraza[%m]%n
2) Deberemos crear un fichero llamado:
/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
El contenido de este fichero será:
org.apache.cxf.common.logging.Log4jLogger
3) Deberemos ajustar el contenido del fichero applicationContext.xml, dejándolo así:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="firmaPeticion" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt" />
<!-- Ajustamos la verificación de la firma de las peticiones que nos
llegan -->
<entry key="signaturePropFile" value="props/server-trust-store.properties" />
<!-- Ajustamos el desencriptado de los datos de la petición que recibimos -->
<entry key="decryptionPropFile" value="props/server-key-store.properties" />
<entry key="passwordCallbackClass" value="es.ine.cxf.ws.sec.PasswordCallback" />
</map>
</constructor-arg>
</bean>
<bean id="firmaRespuesta" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt" />
<!-- Ajustamos el firmado de las respuestas -->
<entry key="signaturePropFile" value="props/server-key-store.properties" />
<entry key="user" value="desarrollo-internet" />
<!-- Ajustamos el encriptado de las respuestas -->
<entry key="encryptionPropFile" value="props/server-trust-store.properties" />
<entry key="encryptionUser" value="edugarci" />
<entry key="signatureKeyIdentifier" value="DirectReference" />
<entry key="passwordCallbackClass" value="es.ine.cxf.ws.sec.PasswordCallback" />
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
<entry key="encryptionParts"
value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
<entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
</map>
</constructor-arg>
</bean>
<jaxws:endpoint xmlns:tns="http://impl.ws.cxf.ine.es/"
id="calculadora" implementor="es.ine.cxf.ws.impl.CalculadoraImpl"
wsdlLocation="wsdl/calculadoraimpl.wsdl" endpointName="tns:CalculadoraImplPort"
serviceName="tns:CalculadoraImplService" address="/CalculadoraImplPort">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<ref bean="firmaRespuesta" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="firmaPeticion" />
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="abstractLoggingInterceptor" abstract="true">
<property name="prettyLogging" value="true" />
</bean>
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"
parent="abstractLoggingInterceptor" />
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"
parent="abstractLoggingInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outFaultInterceptors>
<cxf:inFaultInterceptors>
<ref bean="loggingInInterceptor" />
</cxf:inFaultInterceptors>
</cxf:bus>
</beans>
No hay comentarios:
Publicar un comentario