I am using java and cxf SOAP webservices. I have enabled schema validation as below but it is not working. I dont have any external xsds. All xsd elements are part of WSDL. Will schemavlaidation= true property does not work if it has no external xsd and all xsd elements are part of WSDL? I placed minOccur and maxOccur attributes.
<jaxws:endpoint id="serviceEndpoint" implementor="#serviceEndpoint"
address="/CreateService" wsdlLocation="classpath:wsdl/Service.wsdl">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
Related
How can I add default WS-addressing to the xml?
<cxf:cxfEndpoint id="endpoint" xmlns:s="http://tempuri.org/"
address="https://uslugaterytws1test.stat.gov.pl/TerytWs1.svc"
endpointName="s:custom"
serviceName="s:TerytWs1"
wsdlURL="classpath:/wsdl/terytws1.wsdl">
<cxf:properties>
<entry key="schema-validation-enabled" value="false" />
</cxf:properties>
<cxf:inInterceptors>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<cxf:cxfEndpoint id="poxyEndpoint" xmlns:s="http://tempuri.org/"
address="http:localhost:5678/myproxy"
endpointName="s:customProxy"
serviceName="s:TerytWs1Proxy"
wsdlURL="classpath:/wsdl/terytws1Proxy.wsdl">
<cxf:properties>
<entry key="schema-validation-enabled" value="false" />
</cxf:properties>
<cxf:inInterceptors>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref component-id="wssOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref component-id="wssOutInterceptor" />
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<camelContext id="proxyTerytContext" xmlns="http://camel.apache.org/schema/blueprint">
<route id="route-TerytWs1">
<from id="inbound" uri="cxf:bean:proxyEndpoint?dataFormat=CXF_MESSAGE" />
<to id="outbound" uri="cxf:bean:endpoint?dataFormat=CXF_MESSAGE" />
</route>
</camelContext>
When I send request to http:localhost:5678/myproxy then I get:
<faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
<faultstring xml:lang="en-US">An error occurred when verifying security for the message.</faultstring>
I have read many similar questions and examples but haven't found the solution for pure cxf xml. I have been trying to solve this for 2 days. Now I'm crying.
EDIT:
This is an original wsdl: https://uslugaterytws1test.stat.gov.pl/terytws1.svc?wsdl
and this is my proxy to it: https://github.com/woblak/training/blob/master/teryt_testProxy.wsdl
user: TestPubliczny
pass: 1234abcd
There are some examples in the Camel unit tests which test CXF endpoints with WS-Addressing enabled; WSAddressingTest-context.xml seems like it might be relevant to your question?
Here, WS-Addressing has been enabled on a CXF endpoint by adding the wsa:addressing element in features:
<cxf:cxfEndpoint...>
<cxf:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing" />
</cxf:features>
</cxf:cxfEndpoint>
The error seems to be related to security. You have an interceptor configured (wssOutInterceptor) but there's no source code. Perhaps you should look there to see if you're setting the auth details.
I would also add message logging so you can see the content of the payload sent to the target and verify that it contains your credentials.
Or, if you're using the Camel CXF namespace ( xmlns:cxf="http://camel.apache.org/schema/cxf") you can use:
<cxf:cxfEndpoint ... loggingFeatureEnabled="true">
...
</cxf:cxfEndpoint>
I have been researching how to implement a web service client policies from a .wsdl file.
The policies of the web services implicates a signature and encryption using a .jks file with the necessary keys (asymmetric privateKey for signing, and a symmetric privateKey for encryption). The policy is: username:oracle/wss10_username_token_with_message_protection_service_policy.
I am able to make the .xsd files (request, response and service objects) using the wsimport tool for java (or with cxf or axis2). What i can't resolve is how to make the correct policy.
Is there any way to automatically generate the policies from the .wsdl or do i have to make them by myself
The username:oracle/wss10_username_token_with_message_protection_service_policy is solved with spring ws this way:
<!-- == Ougoing interceptor == -->
<bean id="loginOutgoingWss4jSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
<property name="securementActions" value="Timestamp Signature Encrypt" />
<!-- == Set Outgoing Signature properties == -->
<property name="securementUsername" value="alias"/>
<property name="securementPassword" value="aliasPass"/>
<property name="securementSignatureKeyIdentifier" value="DirectReference"/>
<property name="securementSignatureCrypto" ref="cryptoFactoryBean" />
<property name="securementSignatureParts" value="{Element}{}Body;{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;" />
<!-- == Set Outgoing Encryption properties == -->
<property name="securementEncryptionUser" value="alias"/>
<property name="securementEncryptionCrypto" ref="cryptoFactoryBean" />
<property name="securementEncryptionKeyIdentifier" value="DirectReference"/>
<property name="securementEncryptionParts" value="{Content}{}Body;" />
</bean>
<!-- == Incoming interceptor == -->
<bean id="loginIncomingWss4jSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
<property name="validationActions" value="Timestamp Signature Encrypt" />
<!-- == Set Validations Response, This validate signature and decrypts response == -->
<property name="validateResponse" value="true" />
<!-- The lower operation validation. Less time consume-->
<property name="validateRequest" value="false" />
<property name="enableSignatureConfirmation" value="false"/>
<!-- == Set Incoming Signature/Decryption keystore == -->
<property name="validationDecryptionCrypto" ref="cryptoFactoryBean" />
<property name="validationSignatureCrypto" ref="cryptoFactoryBean" />
<!-- Sets the {#link org.apache.ws.security.WSPasswordCallback} handler to use when validating messages -->
<property name="validationCallbackHandler">
<bean class="org.springframework.ws.soap.security.wss4j2.callback.KeyStoreCallbackHandler">
<property name="privateKeyPassword" value="aliasPass"/>
</bean>
</property>
</bean>
If you are using policies in WS-SecurityPolicy (1.1 or later) in your wsdl, no need to generate policies nor make them on client side with Apache CXF. With WS-SecurityPolicy, CXF's security runtime is policy driven.
1) You follow CXF's WSDL-first approach to generate the client code, using either wsdl2java command-line tool or Maven cxf-codegen-plugin (wsdl2java goal). This is described in CXF doc's How to develop a client.
2) Following CXF's doc on WS-SecurityPolicy usage, you configure the client security properties for the wsdl port you want to use, either using JAX-WS API (on the client's RequestContext) or Spring XML configuration. For the list of possible properties, there are the generic XML security ones and WS-Security-specific ones. Example with Spring XML for UsernameToken policy (from Glen Mazza's blog samples ):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItPort" createdFromAPI="true">
<!-- Use this for the UsernameToken Symmetric Binding w/X.509 for secret key derivation -->
<jaxws:properties>
<entry key="ws-security.username" value="alice"/>
<entry key="ws-security.callback-handler" value="client.ClientPasswordCallback"/>
<entry key="ws-security.encryption.properties" value="clientKeystore.properties"/>
<entry key="ws-security.encryption.username" value="myservicekey"/>
</jaxws:properties>
<!-- Use this for the UsernameToken Symmetric Binding w/UT password for secret key derivation -->
<!--jaxws:properties>
<entry key="ws-security.username" value="alice"/>
<entry key="ws-security.callback-handler" value="client.ClientPasswordCallback"/>
</jaxws:properties-->
</jaxws:client>
</beans>
Put this in /cxf.xml on the class path. Warning: the example is using a CallbackHandler subclass (client.ClientPasswordCallback in this example) to provide the password. So you'll need to provide your own implementation.
3) Back to CXF doc's How to develop a client - last part - in the application code, initialize the client using JAX-WS API with arguments: a) the location of the WSDL (URL) having the WS-SecurityPolicy policies (you already have that, as far as I understand); b) service and port's QNames to be used by the client, as defined in the WSDL:
final Service service = Service.create(wsdlLocation, SERVICE_QNAME);
final DoubleItPortType transportPort = service.getPort(PORT_QNAME, DoubleItPortType.class);
4) Make sure you have cxf-rt-ws-policy and cxf-rt-ws-security modules on the classpath at runtime to enable WS-SecurityPolicy support.
I have a SOAP request similar to this:
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
....
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<MyRequest>
<Param>3</Param>
</MyRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
and the response should be like
<SOAP-ENV:Envelope>
<SOAP-ENV:Header>
....
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<MyResponse>
<Value>3234</Value>
<Value>542</Value>
</MyResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
My problem is that my JAX-WS SOAP service expects a namespace e.g. xmlns="http://myapp.example.com" in MyRequest. It also adds this namespace to the MyResponse element too.
I have managed to write an Interceptor that will add my apps target namespace to the request message if it is blank. This works fine.
My issue right now is that I am not sure how to remove this namespace from the response message.
I know the best solution would be to have clients use namespaces, however this is not possible on the project I am working on.
CXF comes with Transformation Feature, Please have look here
A sample bean extract from page.
<bean id="transformFeature" class="org.apache.cxf.feature.StaxTransformFeature">
<property name="outTransformElements">
<map>
<!-- change "book" to "thebook" -->
<entry key="book" value="thebook"/>
<!-- drop the namespace from "book" -->
<entry key="{http://books}book" value="book"/>
<!-- qualify "book" with "http://books" -->
<entry key="book" value="{http://books}thebook"/>
<!-- change namespace to "http://books" for all the elements with the "http://book" namespace -->
<entry key="{http://book}*" value="{http://books}*"/>
</map>
</property>
</bean>
That's pretty broad since we don't know what you are using, but if you can use Metro (JAX-WS) then you can take advantage of what they call SOAPMessage Handler (have a look here). It works pretty much like a Servlet filter component.
Have something that implements SOAPHandler<SOAPMessageContext> and remove the namespace declaration(s) there.
Moving from web.xml to OSGi Http Whiteboard pattern created bundle-context.xml
how to pass below properties from web.xml in jspServletfilter's osgi:service-properties
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
I tried below solution but it does not work.
<bean id="jspServlet" class="com.test.servlet.web.servlet.TestJSPServlet"/>
<osgi:service ref="jspServlet" interface="javax.servlet.Servlet" >
<osgi:service-properties>
<entry key="osgi.http.whiteboard.filter.name" value="JSPServlet" />
<entry key="osgi.http.whiteboard.servlet.pattern" value-ref="jspPatternsList"/>
<entry key="osgi.http.whiteboard.context.select" value="(osgi.http.whiteboard.context.name=cb)" />
<entry key="servlet.init.el-ignored" value="true" />
</osgi:service-properties>
</osgi:service>
I just checked one more time, but if I'm not completely wrong the OSGi spec doesn't handle JSPs in a certain way. So what you are trying to do there doesn't work with the Apache Felix implementation.
The only way to have JSPs working with the Http Whiteboard approach is to switch to the Pax - Web Project. As it not only supports the Whiteboard approach (spec compliance is still work in progress, 6.0.0-SNAPSHOT) but also more then there is in the spec right now.
To achieve what you want the following is needed with Pax-Web:
<!-- JSP handling -->
<service id="jspMapping" interface="org.ops4j.pax.web.extender.whiteboard.JspMapping">
<bean class="org.ops4j.pax.web.extender.whiteboard.runtime.DefaultJspMapping">
<property name="urlPatterns">
<array>
<value>/jsp</value>
</array>
</property>
</bean>
</service>
an example can also be found in the samples of the pax-web project.
We recently migrated from CXF 2.2.3 to CXF2.7.17 and i don't see anymore any cxf logs in the log file they are supposed to go to.
As far as i know our configuration to log CXF is pretty standard.
In the cxf.xml we have
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="logInbound" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="logOutbound" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="logOutbound" />
</cxf:outFaultInterceptors>
<cxf:inFaultInterceptors>
<ref bean="logInbound" />
</cxf:inFaultInterceptors>
</cxf:bus>
The tomcat (7 with java 7) is launched with the parameter :
-Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger
And in our lo4g prop file :
log4j.appender.cxfAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.cxfAppender.file=/usr/users/theuser/DATA/LOG/theappli-web/theappli-CXF.log
log4j.appender.cxfAppender.layout=com.thefirm.log.PatternLayout
log4j.appender.cxfAppender.layout.ConversionPattern=%D %h TOMCAT[-%C{1}] : %X{UTILISATEUR}-%X{JSESSIONID};%p;%M;ESV;%X{CODE_MSG};%m;;%n
log4j.logger.org.apache.cxf.interceptor=INFO, cxfAppender
log4j.additivity.org.apache.cxf.interceptor=false
Nothing has changed in these files during the migration. Has anyone faced the same problem after migrating ?
I finally found an answer in the cxf migration log.
The Logging interceptors now log using service specific categories/loggers >instead of just LoggingInInterceptor/LoggingOutInterceptor. The names of the >logger that is used is
org.apache.cxf.services.ServiceName.PortName.PortTypeName. This allows the user >to configure specific per service filters and formatters in their logging >configuration
The solution was to replace log4j.logger.org.apache.cxf.interceptor=INFO, cxfAppenderwith log4j.logger.org.apache.cxf.=INFO, cxfAppender.