I am having a hard time getting cxf to validate an xml request that my service creates for a 3rd party.
My project uses maven. Here is my project structure
Main Module :
+ Sub-Module1 = Application
+ sub-Module2 = Interfaces
In Interfaces, inside src/main/resources I have my wsdl and xsd.
so, src/main/resources
+ mywsdl.wsdl.
+ myschema.xsd
The interface submodule is listed as a dependency in the Application-sub-module.
inside Application sub-module, there is a cxsf file in src/maim/resources.
<jaxws:client name="{myTargerNameSpaceName}port"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:client>
AND:.
<jaxws:endpoint name="{myTargetNameSpaceName}port"
wsdlLocation="/mywsdl.wsdl"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
I tried changing the "name="{myTargetNameSpaceName}port" to "name="{myEndPointName}port"
But to no anvil.
My application works. But it just do not validate the xml I am producing that has to be consumed by a 3rd party application.
I would like to get the validation working, so that any request that I send would be a valid one.
Any suggestions?
Just add #org.apache.cxf.annotations.SchemaValidation annotation on your service implementation class and schema validation will work.
First ensure that the value of the name attribute is {NAMESPACE}PORT_NAME where NAMESPACE is your namespace URI and PORT_NAME is the name of your WSDL port. Without seeing your WSDL, I don't know if you named your WSDL port "port" or if you are just giving a sanitized example.
For example, my WSDL namespace is "http://example.com/services" and the name of my WSDL port element is "myPort", the Spring configuration would look like this
<jaxws:endpoint name="{http://example.com/services}myPort" >
...
See "CreatedFromAPI" attribute description in CXF docs
If that doesn't solve your problem, try looking at the wsdl_first example code, upgrading your CXF version, and/or posting your question with test code demonstrating your issue to the CXF user list.
We had similar issues. CXF 2.3.1 fixed the issue for us on incoming messages but not outgoing messages.
https://issues.apache.org/jira/browse/CXF-3233
We work around it by marshaling the messages and validating them within the server before sending them out through the CXF interceptor chain. We validate using org.springframework.xml.validation.XmlValidator.
I'm hoping a future version of CXF will solve this but this is what we do for now.
Related
In one of my projects i have to set the ETag header in responses and read the if-none-matched header in the incoming requests. As of now i have implemented this using Apache CXF Filters however as i searched and found, the same functionality can be done by using interceptors as well. what are the significant advantages and/or disadvantages that i will have to experience if i proceed with CXF filters??
as of now i have implemented the filter and it works fine What would be the best practices in using a filter?
Here's a quote from http://cxf.apache.org/docs/jax-rs-filters.html.
Difference between JAXRS filters and CXF interceptors
JAXRS runtime flow is mainly implemented by a pair of 'classical' CXF interceptors. JAXRSInInterceptor is currently at Phase.UNMARSHAL (was at Phase.PRE_STREAM before CXF 2.2.2) phase while JAXRSOutInterceptor is currently at Phase.MARSHAL phase.
JAXRS filters can be thought of as additional handlers. JAXRSInInterceptor deals with a chain of Pre and Post Match ContainerRequestFilters, just before the invocation. JAXRSOutInterceptor deals with a chain of ContainerResponseFilters, just after the invocation but before message body writers get their chance.
Sometimes you may want to use CXF interceptors rather than writing JAXRS filters. For example, suppose you combine JAXWS and JAXRS and you need to log only inbound or outbound messages. You can reuse the existing CXF interceptors :
<beans>
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxrs:server>
<jaxrs:inInterceptors>
<ref bean="logInbound"/>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<ref bean="logOutbound"/>
</jaxrs:outInterceptors>
</jaxrs:server>
<jaxws:endpoint>
<jaxws:inInterceptors>
<ref bean="logInbound"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutbound"/>
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
Reusing other CXF interceptors/features such as GZIP handlers can be useful too.
At the moment it is not possible to override a response status code from a CXF interceptor running before JAXRSOutInterceptor, like CustomOutInterceptor above, which will be fixed.
For a SOAP web service, I have a working example of the configuration for PasswordDigest authentication via camel-cxf and WSS4J :
<camel-cxf:cxfEndpoint id="myService"
address="${ws.endpoint.address}"
serviceName="es:MyService"
wsdlURL="wsdl/myservice.wsdl"
endpointName="es:MyServicePort"
serviceClass="com.us.MyServiceEndpoint"
xmlns:es="http://us.com/services/MyService">
<camel-cxf:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordDigest"/>
<entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
</map>
</property>
</bean>
</camel-cxf:inInterceptors>
</camel-cxf:cxfEndpoint>
We have a request to enable the same resource for BASIC authentication - how can this configuration be modified to do that?
I have changed the following line and tested via SOAP UI:
<entry key="passwordType" value="PasswordText"/>
However the result is a SOAP fault from UsernameTokenValidator.java:
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
UsernameToken: Password hashing policy not enforced</faultstring>
</soap:Fault>
If anyone has some guidance here it would be appreciated.
You are mixing up the two different ways of configuring WS-Security in CXF.
The "PolicyBasedWSS4JInInterceptor" is used when you have a WS-SecurityPolicy to configure security. You don't need to actually add it at all, as CXF will automatically add it to the interceptor chain. It's configured via the configuration tags specified here: http://cxf.apache.org/docs/ws-securitypolicy.html. The configuration tags you are specifying as "properties" are ignored for the security policy case.
If you want to configure security via a policy in this case, you will need to remove the "HashPassword" policy if you want to support plaintext passwords.
If you want to only configure via "actions" you should be using the "WSS4JInInterceptor" instead (which the policy based interceptor extends).
Colm.
The WSS-PasswordType needed to change from PasswordText to PasswordDigest.
I have some problems with my server-client communication via web services with Apache CXF framework. I want to log the server errors to an external file instead of terminal. Piece of code for server;
server= new JaxwsNotificationBroker("Hello",..);
server.setAddress("http://localhost:" + brokerPort + "/wsn/NotificationBroker");
And I tried this for logging;
server.getInInterceptors().add(new LoggingInInterceptor());
server.getOutInterceptors().add(new LoggingOutInterceptor());
But it gives the error The method getInInterceptors() is undefined for the type JaxwsNotificationBroker.
Is there any method to log the errors for JaxwsNotificationBroker?
Thank you
You can add loggingInInterceptor & logOutInterceptor inside cxf:bus
<cxf:bus>
<cxf:ininterceptors>
<ref bean="loggingInInterceptor" />
</cxf:ininterceptors>
<cxf:outinterceptors>
<ref bean="logOutInterceptor" />
</cxf:outinterceptors>
</cxf:bus>
add this to your spring config file, if you are using spring:
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
don't forget to add cxf namespace as
xmlns:cxf="http://cxf.apache.org/core"
If you use log4j for logging you must put a META-INF/cxf/org.apache.cxf.Logger file onto the classpath with the 'org.apache.cxf.common.logging.Log4jLogger' class name in it as a single line, otherwise cxf will use the JavaTM 2 platform's core logging facilities.
For some reason, gnodet wanted to keep all the WS-N stuff as independent from CXF as possible and only rely on pure JAX-WS stuff. Thus, nice methods for things like the CXF interceptors aren't possible. :-(
Looking at the code, the only option right now would be to write a subclass of JaxwsEndpointManager that would call the super.register method, then cast it to the CXF EndpointImpl, and set the interceptors on there. Not really ideal. :-(
I'm trying to write a "Secure Hello World" web service using Apache CXF also; I should note that I'm kind of new to Java and WS-* stuff.
Basically, what I want to do is a hello-world web service with soap messages to and from this web service signed and encrypted using x.509 certificate(s).
I have already read the tutorial on Apache CXF site about WS-Security but; I want to use WS-SecurityPolicy instead of Interceptors.
Can anyone point me in the right direction?
Here's a blog with details on using Apache CXF: Adding X.509 security headers to Apache CXF SOAP calls (WS-SecurityPolicy method)
There's also a tutorial with source code configured for using the WS-SecurityPolicy Method.
EDIT: fixed broken link, added link to tutorial.
There is now a good overview of the various settings for WS-SecurityPolicy on the CXF site, and it references the link above.
In a nutshell (in case the links are blown away again), the WS-SecurityPolicy is configured similar to the CXF interceptor method described on the CXF wiki except for a few changes in the cxf.xml and the cxf-servlet.xml:
cxf.xml
<jaxws:client name="{http://myport" createdFromAPI="true">
<!-- You will need to add the corresponding values to a properties file -->
<jaxws:properties>
<entry key="ws-security.callback-handler" value="client.ClientKeystorePasswordCallback"/>
<entry key="ws-security.encryption.properties" value=keystore.properties"/>
<entry key="ws-security.signature.properties" value="keystore.properties"/>
<entry key="ws-security.encryption.username" value="myservicekey"/>
</jaxws:properties>
cxf-servlet.xml
<jaxws:properties>
<entry key="ws-security.callback-handler">
<ref bean="myPasswordCallback"/>
</entry>
<entry key="ws-security.encryption.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.signature.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.encryption.username" value="useReqSigCert"/>
</jaxws:properties>
Since web services work over HTTP, you can secure them by using the HTTPS protocol.
Here is a resource that can help point you in the right direction: Using JAX-WS-Based Web Services with SSL
While this resource is for JAX-WS, you should find that a lot of it will carry over to Apache CXF.
Cheers.
I'm wondering about Spring 3.0 whether it provides an automatically generated service definition page after I defined services.
With SOAP we have a WSDL file which contains WHAT, HOW and WHERE we can call a service.
Is that possible with Spring 3.0 or not?
Yes it does. Just add "?WSDL" to the URL of your Spring-generated web service and you'll get the definition. Also you can append "?xsd=1" instead and you'll get the schema you need (this is referenced also from the WSDL).
You can use an MBeanExporter to expose all of your services via JMX, which would be viewable through a JMX dashboard on your container (IE Tomcat, Jboss, etc). This is an easy way to account for 'what is deployed'. Your question is not entirely clear what sort of artifact you're looking for though.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="true"/>
</bean>
Will automatically export all of your defined beans as MBeans. Usually that's not entirely what you want, so alternatively, you'll specify them manually.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
</bean>
I agree with Chochos.
These[?wsdl, ?xsd=N] are universal standard to find the service definition file and any Datacontract defined in the wsdl.
example:
if http://localhost:8080/MyService is your service endpoint then it is service container's responsibility to make the WSDl available at http://localhost:8080/MyService,
by default.
The answer is Yes,
Use tag in your message dispatcher spring context file.
if your message dispatcher bean id is spring-ws then the spring context file for it would be spring-ws-servlet.xml.
In that context file,
import the namespace http://www.springframework.org/schema/web-services/web-services-2.0.xsd
xmlns:sws="http://www.springframework.org/schema/web-services".
then use the tag dynamic-wsdl from this namespace.
Also, you can set attributes for it like portType, binding and id. This will generate the wsdl file for you. You can view it by querying for it in the browser
/.wsdl