PUNTO ÚNICO DE NOTIFICACIONES PARA TODAS LAS ADMINISTRACIONES PÚBLICAS - DEHú
Guía de generación de un cliente PUC en java
Equipo de desarrollo Punto único de Notificaciones para todas las AAPP - DEHú
Versión 1.0
Guía de generación de un cliente PUC en java Página 1 de 13
Índice de contenidos
1. Introducción ... 2
1.1 Historial de versiones ... 2
1.2 Objetivo del documento ... 2
2. Consideraciones previas ... 3
2.1 Entorno ... 3
2.2 Rutas ... 3
2.3 Características generales ... 3
3. Generación del cliente... 5
4. Apéndice A ... 12
Guía de generación de un cliente PUC en java Página 2 de 13
1. Introducción
1.1 Historial de versiones
Versión Fecha Descripción de los cambios 1.0 21/02/2018 Versión inicial del documento
1.2 Objetivo del documento
Este documento es una guía para la generación de un cliente en java del servicio web que un Punto de Concentración de Notificaciones (en adelante PUC) tiene que implementar para relacionarse con el Punto Único de Notificaciones para todas las Administraciones Públicas que actúa como servidor.
En concreto se han implementados los dos métodos:
agregarEnvio()
actualizarEnvio()
Guía de generación de un cliente PUC en java Página 3 de 13
2. Consideraciones previas
2.1 Entorno
El entorno utilizado en esta guía consta de los siguientes elementos:
IDE eclipse neon 3
Versión ApacheCxf 3.2.1
Java 1.8.0_73 y 1.7.0_80
Tomcat 8.5
No se ha utilizado Maven, ni tampoco se ha utilizado el framework de spring ni para la inyección de dependencias ni para utilizar su producto de spring-ws, con objeto de ser lo más neutral posible.
En el almacén cacerts del servidor (web o aplicaciones) o en el IDE de desarrollo, se tendrá que tener los certificados referentes a *.redSara.es para la comunicación con el protocolo SSL.
2.2 Rutas
Se puede encontrar el WSDL y el endpoint en las siguientes rutas
Entorno Tipo Ruta Codificación
PRE WSDL https://pre-lemaws.redsara.es/wsdl/PucA_Dehu/PucA-
Dehu-Ws_pre.wsdl Document-
Literal PRE Endpoint https://pre-lemaws.redsara.es/ws/envios
Los WSDL se han construido siguiendo las especificaciones de estandarización e interoperabilidad de SOAP1.1 contempladas en las organizaciones de WS-I y W3C.
https://www.w3.org/TR/2001/NOTE-wsdl-20010315
2.3 Características generales
El cliente de los servicios web se ha generado teniendo en cuenta las siguientes características:
Generación mediante contract first en Cxf con el correspondiente wsdl de cada entorno.
Se han de fijar propiedades del protocolo como la de not chuncked.
El cliente debe implementar WS-Security.
Ws-security puede implementarse de varias formas, mediante WS-SecurityPolicy o a con los interceptores ya predefinidos en la librería org.apache.cxf.ws.security.wss4j a través de las clases de WSS4JOutInterceptor y WSS4JInInterceptor y sus diferentes propiedades.
Guía de generación de un cliente PUC en java Página 4 de 13 En este cliente se ha utilizado el interceptor WSS4JOutInterceptor por estar generando una petición del cliente. Para procesar la respuesta, se podrá utilizar WSS4JInInterceptor lo que permitirá validar si viene firmado e incluso identificar la firma (opcional de cada sistema).
Guía de generación de un cliente PUC en java Página 5 de 13
3. Generación del cliente
Se Crea un Dynamic web Project.
Se genera el cliente con CXF a través del WSDL.
Guía de generación de un cliente PUC en java Página 6 de 13 Para evitar problemas con el espacio de nombres y los paquetes se ha optado por no utilizar número del tipo 1.0 en la nomenclatura (ver imágenes).
Se debe marcar:
El check Enable processing of implicit SOAP headers para generar los elementos de cabecera, aunque en este servicio no haya necesidad
El check Enable Auto Name Resolution para evitar los conflictos en los nombres con la misma denominación.
Guía de generación de un cliente PUC en java Página 7 de 13
Se instancian los interceptores del WS-Security. Se genera una nueva clase que recupera la clave privada del certificado del keyStore y no se permitirá notChunked.
Se genera un fichero de properties, necesario para la ejecución de WSS4J, donde se indicará la interfaz de Crypto para obtener las claves y certificados para el cifrado/descifrado y para la creación/verificación de firmas. Además se incluirán otras propiedades que indican el alias, la localización del almacén, etc.
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Me rlin
org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=XXXXX org.apache.ws.security.crypto.merlin.keystore.alias=XXXXXX
org.apache.ws.security.crypto.merlin.keystore.file=D\:\\XXXXXX\\keystore.jks
Guía de generación de un cliente PUC en java Página 8 de 13
Se instancian los interceptores de WSS4J. Se especifican las propiedades necesarias para configurar el ws-security y firmar la petición en la clase que contiene la creación del cliente, en el main.
//Generamos el cliente para inyectarle el WS-Security
Map<String,Object> inProps = new HashMap<String,Object>();
Map<String,Object> outProps = new HashMap<String,Object>();
//... // how to configure the properties is outlined below;
outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.USER, "micc");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, KeystorePasswordCallback.class.getName());
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties");
outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
Guía de generación de un cliente PUC en java Página 9 de 13 outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "false");
outProps.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE,"true");
outProps.put(WSHandlerConstants.SIG_ALGO,
"http://www.w3.org/2000/09/xmldsig#rsa-sha1");
outProps.put(WSHandlerConstants.SIG_C14N_ALGO,
"http://www.w3.org/2001/10/xml-exc-c14n#");
outProps.put(WSHandlerConstants.SIG_DIGEST_ALGO,
"http://www.w3.org/2001/04/xmlenc#sha256");
outProps.put(WSHandlerConstants.SIGNATURE_PARTS,
"{}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION,"true");
Client client = ClientProxy.getClient(port);
//Aunque estén deprecados en el CXF 3 nos sirve para depurar client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
//Generamos los interceptores que se encargan de ello
//WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
//Añadimos los interceptores
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getInInterceptors().add(wssIn);
Como se ha indicado el servicio debe ser notChunked y para ello se debe de especificar en la creación del Cliente.
Guía de generación de un cliente PUC en java Página 10 de 13 Client client = ClientProxy.getClient(port);
//Interceptores deprecated en cxf 3
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
//Indicación de no permitir Chunked
final HTTPConduit httpConduit = (HTTPConduit)
ClientProxy.getClient(port).getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(1000);
policy.setReceiveTimeout(5000);
policy.setAllowChunking(false);
httpConduit.setClient(policy);
Guía de generación de un cliente PUC en java Página 11 de 13 La implementación está en el fichero adjunto.
Guía de generación de un cliente PUC en java Página 12 de 13
4. Apéndice A
Al generar el cliente se puede dar el siguiente error:
Caused by: org.xml.sax.SAXParseException; systemId: jar:file:/C:/XXXXX/cxf/apache- cxf-2.7.18/lib/jaxb-xjc-
2.2.6.jar!/com/sun/tools/xjc/reader/xmlschema/bindinfo/binding.xsd; lineNumber:
52; columnNumber: 88; schema_reference: fallo al leer el documento de esquema 'xjc.xsd' porque no se permite el acceso 'file' debido a una restricción definida por la propiedad accessExternalSchema.
Para solucionarlo se ha creado el fichero properties denominado jaxp.properties, en la ruta de nuestro java /path/to/jdk1.8.0/jre/lib con el siguiente contenido:
javax.xml.accessExternalSchema = all