CXF configurar bus cliente, servidor en un mismo servicio

Tengo un servicio que hace de proxy. La peticion que le llega la envia a otro Servicio Web y este otro devuelve la respuesta.

Por un lado tengo un modulo: cliente-servicio_externo.
Por otro lado tengo el modulo: servidor-proxy.

El cliente es una dependencia del servidor-proxy, para que mediante la configuracion de Spring, llamar al servicio externo.

	<cxf:bus bus="clientPaxaseBus">
		<cxf:features>
			<cxf:logging />
		</cxf:features>
		<cxf:inInterceptors>
			<ref bean="checkResponse" />
			<bean class="org.apache.cxf.ws.security.wss4j.DefaultCryptoCoverageChecker" />
		</cxf:inInterceptors>
		<cxf:outInterceptors>
			<ref bean="SignRequest" />
		</cxf:outInterceptors>
	</cxf:bus>
		
	<jaxws:client id="clientPaxaseConsultaIdentidad" address="#{url}/consultarIdentidad" bus="clientPaxaseBus"
		serviceClass="es.map.xml_schemas.PeticionPortType"/>

Pongo una configuracion de BUS generica, para todos los clientes. Especifico el nombre del bus: bus=”clientPaxaseBus”.

	<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

	<bean id="cdi" class="es.depontevedra.soap.interoperabilidad.identidad.services.spi.ConsultaIdentidadEnPaxase" />
	<jaxws:endpoint id="cdiService" implementor="#cdi" address="/consultaidentidad"
		publishedEndpointUrl="http://${service.host}:${service.port}/${service.wsname}/consultaidentidad">
		<jaxws:inFaultInterceptors>
			<ref bean="logInbound" />
		</jaxws:inFaultInterceptors>
		<jaxws:inInterceptors>
			<ref bean="logInbound" />
		</jaxws:inInterceptors>
		<jaxws:outFaultInterceptors>
			<ref bean="logOutbound" />
		</jaxws:outFaultInterceptors>
		<jaxws:outInterceptors>
			<ref bean="logOutbound" />
		</jaxws:outInterceptors>
	</jaxws:endpoint>

Evito la configuracion bus, poniendo los interceptors a mano en cada endpoint. No he sido capaz de generar un cxf:bus generico nombrando o etiquetandolo de alguna manera. Esta solucion no me gusta, pero funciona. A ver si encuentro una manera mas limpia…

CXF configurar bus cliente, servidor en un mismo servicio

Cliente del “Servicio de Verificación y Consulta de Datos: Plataforma de Intermediación” con CXF

Me ha tocado realizar un cliente para este Servicio Web del Estado (Español).
En los documentos adjuntos, hay mucha informacion relativa a lo que hace y como quiere los datos.
Sobre seguridad no indica nada mas que permite: WS-Security, XMLDSig y Xades. Que se tiene que firmar, pero no indica, que algoritmos hay que usar, como firmar las cabeceras, que partes hay que firmar, etc. Cosa sorprendente cuando ves que hay varias maneras de firmar y de hacer las cosas. Pero te dan una peticion y una respuesta tipo. En base a esa peticion he ido realizando pruebas y puedo afirmar que ya lo tengo.

En CXF recomiendan el uso de WS-Policy siempre y cuando el WSDL contenga estos apartados, pero en este caso tenemos que usar los interceptors de CXF. En el cliente antes de enviar la peticion SOAP, tenemos que firmar el soap:body. Esto se hace en el soap:header, con WS-Security y los Interceptors.

Por lo que he deducido las caracteristicas de WS-Security son:

Dejo mi fichero de configuración de spring para CXF y mi fichero de propiedades:

<?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:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:cxf="http://cxf.apache.org/core" xmlns:http="http://cxf.apache.org/transports/http/configuration"
	xmlns:p="http://cxf.apache.org/policy" xmlns:wsa="http://cxf.apache.org/ws/addressing"
	xmlns:wsp="http://www.w3.org/2006/07/ws-policy" xmlns:sec="http://cxf.apache.org/configuration/security"
	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
	xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
	xsi:schemaLocation="
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
	http://cxf.apache.org/transports/http/configuration
	http://cxf.apache.org/schemas/configuration/http-conf.xsd
	http://cxf.apache.org/configuration/security
	http://cxf.apache.org/schemas/configuration/security.xsd
	http://cxf.apache.org/ws/addressing 
	http://cxf.apache.org/schema/ws/addressing.xs
	http://cxf.apache.org/transports/http/configuration 
	http://cxf.apache.org/schemas/configuration/http-conf.xsd
	http://www.w3.org/2006/07/ws-policy	
	http://www.w3.org/2006/07/ws-policy.xsd
	http://cxf.apache.org/policy 
	http://cxf.apache.org/schemas/policy.xsd
	http://cxf.apache.org/core 
	http://cxf.apache.org/schemas/core.xsd
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://cxf.apache.org/jaxws 
	http://cxf.apache.org/schemas/jaxws.xsd">

	<import resource="classpath*:spring-xsd.xml" />
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<http:conduit name="https://localhost:.*">
		<http:tlsClientParameters disableCNCheck="true">
			<!-- <sec:trustManagers> -->
			<!-- <sec:keyStore type="jks" password="cspass" resource="clientKeystore.jks" 
				/> -->
			<!-- </sec:trustManagers> -->
		</http:tlsClientParameters>
	</http:conduit>

	<cxf:bus>
		<cxf:features>
			<cxf:logging />
		</cxf:features>
		<cxf:inInterceptors>
			<ref bean="SignResponse" />
			<bean class="org.apache.cxf.ws.security.wss4j.DefaultCryptoCoverageChecker" />
		</cxf:inInterceptors>
		<cxf:outInterceptors>
			<ref bean="SignRequest" />
		</cxf:outInterceptors>
	</cxf:bus>

	<util:map id="mapKeystorePasswords">
		<entry key="${org.apache.ws.security.crypto.merlin.keystore.alias}" value="${org.apache.ws.security.crypto.merlin.keystore.password}" />
	</util:map>
	
	<bean id="clientPasswordCallback"
		class="es.una.ruta.callback.ClientPasswordCallback" >
		</bean>

	<bean id="url" class="java.lang.String">
		<constructor-arg
			value="https://${paxase.host}:${paxase.port}/${paxase.wsname}" />
	</bean>
	<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass" value="es.map.xml_schemas.PeticionPortType" />
		<property name="address" value="#{url}/consultarIdentidad" />
	</bean>
	<bean id="clientConsultaIdentidad" class="es.map.xml_schemas.PeticionPortType"
		factory-bean="clientFactory" factory-method="create" />

	<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
		id="SignRequest">
		<constructor-arg>
			<map>
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).IS_BSP_COMPLIANT}"
					value="#{T(java.lang.Boolean).FALSE.toString()}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).MUST_UNDERSTAND}"
					value="#{T(java.lang.Boolean).FALSE.toString()}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).ACTION}"
					value="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIGNATURE}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).USER}"
					value="${org.apache.ws.security.crypto.merlin.keystore.alias}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_PROP_FILE}"
					value="client_sign.properties" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_KEY_ID}"
					value="${signature.key.identifier}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_ALGO}"
					value="#{T(org.apache.ws.security.WSConstants).RSA_SHA1}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_DIGEST_ALGO}"
					value="#{T(org.apache.ws.security.WSConstants).SHA1}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_C14N_ALGO}"
					value="#{T(org.apache.ws.security.WSConstants).C14N_EXCL_OMIT_COMMENTS}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIGNATURE_PARTS}"
					value="#{'{}{' + T(org.apache.ws.security.WSConstants).URI_SOAP11_ENV + '}' + T(org.apache.ws.security.WSConstants).ELEM_BODY + ';'}" />
               	<entry key="#{T(org.apache.ws.security.handler.WSHandlerConstants).PW_CALLBACK_REF}" 
					value-ref="clientPasswordCallback" />
			</map>
		</constructor-arg>
	</bean>

	<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
		id="SignResponse">
		<constructor-arg>
			<map>
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).ACTION}"
					value="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIGNATURE}" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_PROP_FILE}"
					value="client_sign.properties" />
				<entry key="#{T(org.apache.ws.security.handler.WSHandlerConstants).PW_CALLBACK_REF}" 
					value-ref="clientPasswordCallback" />
				<entry
					key="#{T(org.apache.ws.security.handler.WSHandlerConstants).SIG_ALGO}"
					value="#{T(org.apache.ws.security.WSConstants).RSA_SHA1}" />
			</map>
		</constructor-arg>
	</bean>

</beans>

En mi fichero de propiedades del keystore tengo puesto el tipo de firma:

# Defines which key identifier type to use for signature.
# Valid values are: - "IssuerSerial" - "DirectReference" - "X509KeyIdentifier" - "Thumbprint" - "SKIKeyIdentifier" - "KeyValue" - "EmbeddedKeyName" - "EncryptedKeySHA1"
signature.key.identifier =DirectReference
#
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.file=clientKeystore.jks
org.apache.ws.security.crypto.merlin.keystore.password=cspass
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.alias=myclientkey
Cliente del “Servicio de Verificación y Consulta de Datos: Plataforma de Intermediación” con CXF