Apache CXF Tutorial – WS-Security with Spring
This tutorial will cover adding an authentication component to your web service though WS-Security. If you need an overview of how to setup CXF then you may find our previous tutorial helpful. Another helpful resource is CXF’s own WS-Security tutorial. However, it does not include information on how to setup the client through Spring.
To begin with, make sure you have at least the following .jars in addition to the required base CXF .jars:
spring-beans-2.0.6.jar
spring-context-2.0.6.jar
spring-core-2.0.6.jar
spring-web-2.0.6.jar
wss4j-1.5.1.jar
xmlsec-1.3.0.jar
Now we will add a security interceptor to the server’s Spring configuration file, which we named cxf.xml in the last tutorial in order to match the CXF documentation.
<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">
<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" />
<jaxws:endpoint id="auth"
implementor="com.company.auth.service.AuthServiceImpl"
address="/corporateAuth">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass" value="com.company.auth.service.ServerPasswordCallback" />
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
</beans>
You can change the action and passwordType to do more advanced authentication. In this example, we will simply require all authenticating clients to know a single password specified by the server. If you’d like each client to have it’s own password you can specify that in the callback, which is the next thing we must implement:
package com.company.auth.service;
import java.io.IOException;
import java.util.ResourceBundle;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ServerPasswordCallback implements CallbackHandler {
private static final String BUNDLE_LOCATION = "com.company.auth.authServer";
private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";
private static String password;
static {
final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
password = bundle.getString(PASSWORD_PROPERTY_NAME);
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// Set the password on the callback. This will be compared to the
// password which was sent from the client.
// We can call pc.getIdentifer() right here to check the username
// if we want each client to have it's own password.
pc.setPassword(password);
}
}
The server is now setup to require a password. The password we are requiring is one that we specified in a properties file and then read in through a ResourceBundle. You may find it easier to simply hard code the password on the initial run and then replace it with your own means of authentication once the service is up and running.
If you are running on WebLogic 9, as I was, then you will get an error “java.lang.UnsupportedOperationException: This class does not support SAAJ 1.1“. In order to correct that, make sure your version of the SAAJ classes are being used by adding the following to your weblogic.xml descriptor file:
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
You WebLogic folks must also then set two properties in your WebLogic JDK:
-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
-Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl
We now have to setup the client to supply a password. Firstly, we will create another Spring file at com/company/auth/service/cxfClient.xml to setup the application context for the client:
<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-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.company.auth.service.AuthService"/>
<property name="address" value="http://localhost:7001/authManager/services/corporateAuth"/>
<property name="inInterceptors">
<list>
<ref bean="logIn" />
</list>
</property>
<property name="outInterceptors">
<list>
<ref bean="logOut" />
<ref bean="saajOut" />
<ref bean="wss4jOut" />
</list>
</property>
</bean>
<bean id="client" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" factory-bean="proxyFactory" factory-method="create" />
<bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="user" value="ws-client" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackClass" value="com.company.auth.service.ClientPasswordCallback" />
</map>
</constructor-arg>
</bean>
</beans>
We then need to set the password for our message:
package com.company.auth.service;
import java.io.IOException;
import java.util.ResourceBundle;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ClientPasswordCallback implements CallbackHandler {
private static final String BUNDLE_LOCATION = "com.company.auth.authClient";
private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";
private static String password;
static {
final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
password = bundle.getString(PASSWORD_PROPERTY_NAME);
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// set the password for our message.
pc.setPassword(password);
}
}
Finally, we create the service factory, which is extremely easy since all the work was done in the Spring file:
package com.company.auth.service;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class AuthServiceFactory {
private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
"com/company/auth/service/cxfClient.xml"
});
public AuthServiceFactory() {
}
public AuthService getService() {
return (AuthService) context.getBean("client");
}
}
Congratulations. Your web service now utilizes a basic implementation of WS-Security. Hopefully, that will be enough background to get you on your way.
Tags: CXF, Security, SOA, Spring, Tutorial, Web Services, WebLogic
Web Services Tutorial with Apache CXF | Lumidant said,
February 19, 2008 at 5:23 pm
[...] you are looking for something to learn next then may I suggest our tutorial on adding security to your web service. That tutorial will also show you how to setup the client using Spring, which you may find [...]
Irshad said,
February 23, 2008 at 8:19 am
Thanks,
Can you help us using acegi with CXF with an example.
–Irshad.
Ben said,
February 25, 2008 at 4:10 pm
Hi Irshad,
I would love to, but unfortunately I haven’t gotten a chance to use Acegi yet. Maybe in the near future.
-Ben
Ryan said,
March 4, 2008 at 8:54 pm
Do we need to implement this class: com.company.auth.service.ClientPasswordCallback or is it generated by CXF or Spring somehow? Also, did you re-use the client class from the first example (with a modified target address)?
My attempt at this example is close but the WS-Security part isn’t working from the client side. For what it’s worth, here is my error information as my implementation stands:
INFO: Inbound Message
—————————-
Encoding: UTF-8
Headers: {content-type=[text/xml;charset=UTF-8], connection=[close], Date=[Wed, 05 Mar 2008 00:59:24 GMT], Content-Length=[245],
Server=[Apache-Coyote/1.1]}
Messages:
Message:
Payload: soap:ClientRequest does not contain required Security header.
————————————–
Exception in thread “main” javax.xml.ws.soap.SOAPFaultException: Request does not contain required Security header.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:175)
at $Proxy23.getEmployee(Unknown Source)
at com.company.auth.client.Client.main(Client.java:25)
Caused by: org.apache.cxf.binding.soap.SoapFault: Request does not contain required Security header.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:70)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:208)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:96)
Ben said,
March 10, 2008 at 12:34 am
Ah, yes. You are quite right, Ryan. I’m sorry for leaving that out of the tutorial the first go around. It’s been updated now.
I did not re-use the client class from the first example, but instead used the cxfClient.xml file to setup the client through Spring in this example.
patrick van amstel said,
April 16, 2008 at 1:32 am
Lovely tutorial.
Can you add a zip file with all classes and configuration included? That would be very helpful.
grt Patrick
Glen said,
May 7, 2008 at 9:45 am
Ben, I’m confused on something–where did you tie the AuthServiceFactory class you created at the bottom of your tutorial to the creation of client proxies? I.e., how does Spring know to go to that class in particular to generate the SOAP client? The proxyConfig bean in the app context config file (below) is not explicitly referencing AuthServiceFactory, so I don’t know how Spring realizes it needs to call AuthServiceFactory to generate the client proxies.
….
Thanks,
Glen
Ben said,
May 7, 2008 at 12:36 pm
Hi Glen,
I am not instantiating the AuthServiceFactory through Spring in this example, but rather am using it only to instantiate the AuthService itself. For example, the following should work:
final AuthServiceFactory f = new AuthServiceFactory():
final AuthService service = f.getService();
Tony Murphy said,
May 14, 2008 at 3:52 am
Hi,
I’ve being looking at spring and cxf and then noticed this presentation on parleys, interesting. suggests that restful webservices are the way to go
http://www.parleys.com/display/PARLEYS/REST%20-%20The%20Better%20Web%20Services%20Model
Ckarthi said,
May 14, 2008 at 10:52 pm
Really very good tutorial. [The CXF overview tutorial was too good that using Tomcat i was able to try it out in just 5 minutes.]
Reut said,
June 25, 2008 at 8:11 am
It seems to me that the code for the ServerPasswordCallback is displayed twice, and the code where the client sets the password before caliing the srvice doesn’t appear at all.
am i correct?
Ben said,
July 1, 2008 at 1:42 pm
Hi Reut,
I only see the ServerPasswordCallback displayed once in the article. ClientPasswordCallback is also displayed, which is where the client sets the password.
-Ben
Wes said,
July 7, 2008 at 1:07 pm
Hello Reut,
I have a question for you… I’m running CXF with WSS4J (currently in Jetty6 for testing). I can create the service and validate the password text with username token profile successfully using SOAPUI. However, when I create the client (I’m using Struts2 also tested from a jetty container) I get the following error…
javax.xml.soap.SOAPException: Unable to create message factory for SOAP: Provider org.apache.axis.soap.MessageFactoryImpl not found
The strange part is that if I call the service directly with a test case (even through an action test case) everything works. It’s only when I actually call it inside the jetty container that it fails. Notice… I’m not using axis at all either. That has me confused. Do you have any ideas?
W
Ben said,
July 7, 2008 at 3:46 pm
Hi Wes,
Your problem sounds like a classpath issue. I’m not familiar with Jetty, but I would suggest looking into whether there is some way that you can print out the classpath and make sure that all the .jars that you need are present.
-Ben
Wes said,
July 8, 2008 at 11:17 pm
Hi Ben,
The same thing drove me crazy. I’m using maven and with its transitive dependency management I wasn’t sure if I really was getting a jar from axis in my classpath (even tho I’m using cxf). I ultimately did figure it out thanks to another guy on our team (thx JR). It goes back to the same “WebLogic” issue above…
-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
-Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl
I had to define the com.sun factory for my implementation. Otherwise, it apparently defaults to axis.
As for jetty, it’s create with the maven plugin. Just build and type mvn jetty6:run and you have a container to test your web app in. Very, very nice. Glassfish v3 will be able to do the same.
Thank you for responding. I spend hours chasing this issue.
Wes
Tom said,
July 10, 2008 at 7:56 am
Hi Ben and thx for this tutorial.
For me the web service works and returns the HelloWorld string but doesn’t care of WS Security. I fixed different users on server and client without visible effect. And println insert in both PasswordCallback are not displayed.
That’s strange because it works fine with CXF native frontend, but I cannot find what’s wrong with Spring and WAS.
Did you encounter such problem?
Tom said,
July 10, 2008 at 8:14 am
Forget my previous post, I made a noob mistake in my xml client file. :p
Tom said,
July 10, 2008 at 9:32 am
Re,
This time I’m really stucked… My WS works fine with Spring and WAS 6.1, but when I try to add WS-Security authentication I get this error:
org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)
at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source)
at com.ibm.ws.webservices.engine.xmlsoap.SOAPPart.appendChild(SOAPPart.java:244)
at org.apache.cxf.staxutils.W3CDOMStreamWriter.newChild(W3CDOMStreamWriter.java:81)
at org.apache.cxf.staxutils.W3CDOMStreamWriter.writeStartElement(W3CDOMStreamWriter.java:98)
I dont understand in that WSS works with CXF native frontend. May it be a conflict between CXF and Websphere libraries?
Ben said,
July 10, 2008 at 1:44 pm
Hey Tom,
Check out this link for some WS-specific solutions: http://cwiki.apache.org/CXF20DOC/appserverguide.html#AppServerGuide-Websphere
-Ben
Mike Lou said,
July 31, 2008 at 1:56 pm
Hi Ben,
This is a great tutorial. I have a question on server/client config. If I want to config multiple endpoints in the same config files, is there any way to secure some endpoints and leave the others public (not secure)?
-mike
Ben said,
August 4, 2008 at 2:29 pm
Hi Mike,
The interceptors are setup on a per endpoint basis, so you shouldn’t have any trouble doing that. Simply copy everything between the jaxws:endpoint tags to create a new endpoint and leave out the wss4j interceptor for the endpoints you don’t want to secure.
-Ben
Av said,
August 21, 2008 at 3:13 pm
Nice tutorial.
Do you know if there is a preferred method of authorizing a web service using cxf? I mean, after authentication, one needs to ensure that the specified user is actually authorized to execute the web service method in question. Does cxf offer any support for this, do you know?
Thanks.
Blair said,
August 29, 2008 at 10:29 am
Hello,
This is a great tutorial. Does anyone know if a tutorial like this one exists for a JAXRS (RESTful) service. In my service I pass simple XML back and forth. I try using what is shown here in this tutorial and get a bunch of SOAP errors.
Thanks.
Manisha said,
September 15, 2008 at 1:14 pm
It’s really a great tutorial, I could make it work on my local. Here I am trying to understand the client part, which uses org.apache.ws.security.WSPasswordCallback in ClientPasswordCallback() class. Would really appreciate if you could let me know one thing, if my client is .Net – what changes shall I make ?
Dave said,
November 26, 2008 at 5:04 pm
This is an excellent article! It’s what I’ve been looking for for hours. I’ve followed everything but don’t see how to actually make use of the protected service… Am I supposed to be visiting the address for the protected service (/corporateAuth) or something else?
I’m somewhat familiar with CXF, but am really having trouble understanding how to implement WS-Security. Thank you for your time!
Ben said,
November 26, 2008 at 5:15 pm
Hey Dave,
I agree CXF is really tricky. I think it took me a week or two to get a sample app up and running.
You should read the other CXF tutorial on this site first. It will show you how to create a client to access your service. Definitely do that and create an unprotected service first. Then come back to this writeup and add in the security portions.
-Ben
Dave said,
November 27, 2008 at 11:39 am
Hi Ben,
Thank you for your help! Following your examples definitely cleared up a lot of my questions.
Dipesh said,
December 3, 2008 at 10:17 pm
Very good security tutorial, I was able to set it up quickly and test both swAuth and corporateAuth webservice endpoints.
One thing which I did not realize and got confused is when ‘passwordType’ is ‘PasswordText’, responsibility to validate password lies with the CallbackHandler.
I was trying to send wrong password from client and expecting the call to be rejected by WebService. But it was not happening.
After some google found information on CXF wiki page
http://cwiki.apache.org/CXF20DOC/ws-security.html
This note is present under ‘Username Token Authentication’ section, “Note that for the special case of a plain-text password (or any other yet unknown password type), the password validation is delegated to the callback class”.
After reading this I modified ServerPasswordCallback.handle () method, so that the code looks something like:
After this modification in ServerPasswordCallback, service started responding in correct way. Failed for wrong password and get valid response with correct password.
DeKapx said,
April 26, 2009 at 10:24 pm
Hi Ben,
This is really a very good tutorial. Sometimes back I explore WS-Security using Metro – WSIT. There ‘re multiple types of WS-Security can be created using Metro for example:
1. Message Security using Mutual Certificate
2. Message Security using Symmetric Keys.
and few more. Is there any possibility to create such types of WS-Security using Apache CXF. Any information on this will be a great help.
Thanks in advance.
DeKapx
DeKapx said,
April 26, 2009 at 10:38 pm
Hi Ben,
In addition to my previous comment, there is one scenario in our application. We have Metro based WS-Security enabled web service and its implementation is based on WS-Security using Symmetric Keys. I am trying to hit the service using Apache CXF client but its not working. Is there any compatibility issues with these technologies or is there any way out for this.
DeKapx
Manoj said,
September 22, 2009 at 1:38 am
Hi Ben,
Can you tell me where from this “cxf-extension-soap.xml” and ‘cxf-servlet.xml” have come as you have not mentioned any where about these files.
What should i write in these files?
Manoj
Ben said,
September 22, 2009 at 10:46 am
Hi Manoj,
cxf-extension-soap.xml and cxf-servlet.xml come from the jar files. You do not need to create them yourself
david said,
October 31, 2009 at 6:44 pm
Hi Ben,
Is it possible to have the completed project in a zip file. I could not run the client with my limited spring background.
Also when I use the web services explorer, no matter what password I provide, I get the service executed.
Ben said,
November 2, 2009 at 9:36 am
Hi David, I’m sorry, but I don’t have the code for this tutorial still.
jerome bulanadi said,
November 12, 2009 at 2:30 pm
Hi Ben,
Thanks a lot for the previous tutorial, and this security tutorial. It got me up and running CXF on Tomcat in no time.
Hi Dipesh,
Thanks too, for your handling of wrong client password. It saved me a lot of time searching over CXF documentation.
You dudes rock!
Stalin Mohapatra said,
February 4, 2010 at 11:47 pm
Hi Ben…
This tutorial was of immense help. I did learn a few new things. Keep up the good work and help beginners like us.
Bart Ottenkamp said,
February 9, 2010 at 4:30 am
Hi Ben..
great writing and I got almost everything working…
One thing though: if I set uo de thes ecurity like you explain, I get while calling the service:
com.company.auth.service.ServerPasswordCallback cannot be cast to java.lang.String
And I don’t see what’s happening…
Do you have a clue?
dev said,
July 25, 2010 at 6:57 pm
Hi ,
I try above example to implement the web service security but i am getting this exception
—————————-
ID: 1
Response-Code: 500
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {Content-Length=[361], connection=[close], Date=[Mon, 26 Jul 2010 01:54:38 GMT], Server=[Apache-Coyote/1.1], content-type=[text/xml;charset=UTF-8]}
Payload: ns1:InvalidSecurityAn error was discovered processing the <wsse:Security> header
————————————–
Exception in thread “main” javax.xml.ws.soap.SOAPFaultException: An error was discovered processing the header
can any one help me if , if any one having zip file for running source code ,please provide me
Thanks..
louis gueye said,
August 17, 2010 at 1:08 am
Thanks a lot this saved me much time.
.
The only regret I have is that WSS4*Interceptor interceptors don’t reference an instance but a class name so I could not inject any Spring managed bean to make some more elaborate password checks.
I’ll keep looking for an interceptor that will suit my needs … or create one
Anyway thanks again very much.
Viki said,
August 31, 2010 at 7:16 am
Hi ..
I’ve been struggling with this for a while now .. Is there a new client class that we would have to use …
Could someone please post that ..
Thanks
MDG said,
September 30, 2010 at 7:52 am
Hi Louis,
For referencing a Spring Bean you just have to use a “passwordCallbackRef” like this:
Good luck
MDG said,
September 30, 2010 at 7:56 am
Sorry, seems I had to replace the start and end tag character by their html equivalent.
For referencing a Spring Bean you just have to use a “passwordCallbackRef” like this:
<jaxws:endpoint id=”authSecure”
implementor=”be.ucm.test.webservice.cxf.auth.service.AuthServiceImpl”
address=”/corporateAuth”>
<jaxws:inInterceptors>
<bean class=”org.apache.cxf.binding.soap.saaj.SAAJInInterceptor”/>
<bean class=”org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor”>
<constructor-arg>
<map>
<entry key=”action” value=”UsernameToken”/>
<entry key=”passwordType” value=”PasswordText”/>
<entry key=”passwordCallbackRef” value-ref=”passwordCallback”/>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean name=”passwordCallback” class=”be.ucm.test.webservice.cxf.auth.service.ServerPasswordCallback”>
</bean>
Good luck
MDG said,
September 30, 2010 at 8:01 am
Hi Viki,
You have to call a method like the following one in your client:
private static void authenticatedCall() {
System.out.println( “Hello World: authenticatedCall!” );
AbstractApplicationContext ctx;
JaxWsProxyFactoryBean jaxwsClient=null;
AuthService client=null;
// Initialization of Spring’s Application context
ctx = new ClassPathXmlApplicationContext(“be/ucm/test/webservice/cxf/client/cxfClient.xml”);
ctx.registerShutdownHook();
// Getting a reference to the client Bean
client = (AuthService) ctx.getBean(“client”);
Employee employee = client.getEmployee(“0223938″);
System.out.println(“Server said: ” + employee.getLastName() + “, ” + employee.getFirstName());
}
Of course, this code is for a standalone aplication where you ahev to initialize yourself the Spring’s context.
Erick said,
October 5, 2010 at 3:51 pm
Hi Ben:
I did a WebService implementation on CXF and a Client, all good and all functioning, I followed the steps on your tutorial (which looks pretty good by the way, thanks), and I deployed it without any problem. The thing is that I tried to prove it with mi old client (and my old client is not setting any header on soap client message, and so, the WS should fail ), but all passes correctly, even worse, in this configuration:
If I put something like it doesn’t deploy, it complains about that class not existing, but if I do the same with
and put something like
it doesn’t complain at all, it seems to me if like the “callback” or the security itself it’s “not enabled”. I hope you could help me with this.
Thanks
Erick
Erick said,
October 5, 2010 at 4:02 pm
I’m sorry, the pieces of code didn’t appear, I was refering to if I miswrite the org.apache.cxf.ws.security…WSS4jInterceptor and put a wrong name for it, and the same for the passwordCallvBackClass value, if I miswrite the first it doesn’t deploy, if i miswrite the second, it doesn’t give any exception, it deploys normally and let my client withous ws-security to access the webservice.
Also, befor my jaxws:interceptors declaration, I have a jaxws:properties declaration to enable mtom, that could be the problem? cause I removed the mtom properties, and still it wasn’t working …
Seasons said,
October 29, 2010 at 11:24 pm
You you could make changes to the post name Apache CXF Tutorial – WS-Security with Spring to more catching for your blog post you write. I liked the blog post even sononetheless.
David said,
November 3, 2010 at 6:52 am
Hi!~
Quite helpful post. But, I have a question about how to secure the CLIENT SIDE which means every time client access the web service he or she needs to provide the correct username and password.??
Thank you very much
abhi said,
November 16, 2010 at 12:23 am
can we use same spring configuration with JAX-RS?
example:
please let me know
Krishna said,
February 8, 2011 at 2:41 am
Hi Ben,
Thx 4 a great tutorial..
Am getting the following exception…Not sure what went wrong..
Thx,
Krishna
Krishna said,
February 8, 2011 at 2:42 am
Apache Tomcat/7.0.6 – Error report HTTP Status 500 – type Exception reportmessage description The server encountered an internal error () that prevented it from fulfilling this request.exception javax.servlet.ServletException: Servlet execution threw an exception
root cause java.lang.AbstractMethodError: org.apache.cxf.bus.CXFBusImpl.getProperties()Ljava/util/Map;
org.apache.cxf.message.MessageImpl.calcContextCache(MessageImpl.java:221)
org.apache.cxf.message.MessageImpl.getContextualProperty(MessageImpl.java:204)
org.apache.cxf.message.AbstractWrappedMessage.getContextualProperty(AbstractWrappedMessage.java:164)
org.apache.cxf.interceptor.StaxInInterceptor.getXMLInputFactory(StaxInInterceptor.java:92)
org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:81)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:89)
org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:99)
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:337)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:182)
org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:163)
org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:141)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.6 logs.Apache Tomcat/7.0.6
Sairam said,
March 8, 2011 at 12:20 am
I am getting following exception while invoking the client
8/03/2011 18:06:43 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Interceptor has thrown exception, unwinding now Problems creating SAAJ object model
I using CXF 2.1.4 on Weblogic 10.0. I am using following Server side XML:
Error Stack Trace is as follows:
Exception in thread “Main Thread” javax.xml.ws.soap.SOAPFaultException: Problems creating SAAJ object model
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145)
at $Proxy39.myFile(Unknown Source)
at wsdlclient.myService_myServiceImplPort_Client.main(myService_myServiceImplPort_Client.java:73)
Caused by: org.apache.cxf.binding.soap.SoapFault: Problems creating SAAJ object model
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:96)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:641)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:2102)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1980)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1905)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:600)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:469)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
I have added the Weblogic properties in JDK as well:
-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
-Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl
and also set the prefer-application-packages to:
javax.jws.*
org.apache.*
Could you please tell where the issue could be. Have spent lot of time on this, still no luck
Sridhar said,
May 17, 2011 at 4:40 am
Hi Ben,
Thanks a lot. You have done a great job for us.
This tutorial is really helpful to test the security. I could set up this very quickly and finish the testing easily.
I don’t understand one thing why it is giving the outbound message 2 times. It would be great if you provide your comments.
Once again thanks a lot.
Liav said,
July 7, 2011 at 7:34 am
Hi,
Let’s say i want to distribute the wsdl file to some client who doesn’t support Spring & uses a simple CXF generator (wsdl2java).
Will he be required to supply the ws with the auth password in addition to the service arguments?
Where & how would it be supplied?
Thanks & great job.
Liav.
Guilhem said,
August 15, 2011 at 12:01 am
Hi there
Thanks for this tutorial. I had to adapt it a little because my app is currently using the simple front-end, however I doubt it may be the reason why if is giving an unexpected (to me at least!) behavior.
What happens if I leave both handle methods exactly as you provided them, is, the WS responds no matter which password is supplied by the client. In order to have the WS to actually check for the password being correct I had to modify the server-side handle method as follows:
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// We can call pc.getIdentifer() right here to check the username
// if we want each client to have it’s own password.
if (!pc.getPassword().equals(password))
throw new IOException(“Wrong password!”);
}
So did I miss something? Any ideas?
Thanks in advance.
Guilhem
smith said,
August 30, 2011 at 11:24 pm
I got the following exception:
“java.util.MissingResourceException:Can’t find bundle for base name…”, anyone know how to name the bundle? Thx.
Guilhem said,
September 5, 2011 at 12:37 am
Can anyone help regarding my post from Aug. 15th?
cuyt said,
December 28, 2011 at 9:28 pm
how can we user cxf-rest server and client
Dmitry said,
January 30, 2012 at 3:26 am
Hello!
I’m a confused about the server’s callback handler. The matter is I can’t get to it in the debug mode. After some time researching I found, that WSS4JInInterceptor doesn’t have a callback. Please, see http://stackoverflow.com/questions/9035520/apache-cxf-spring-simple-certificate-authentication/9062076#9062076 for more details.
Can you, please, answer these questions:
1. When do the WSS4JInInterceptor’s callback is called
2. What password do the client sets in WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; pc.setPassword(“”)