Reputation: 3038
I've started learning the Apache CXF with Spring. First of all, I've created a simple client/server model: see here
Now I'm trying to use a simple certificate authentication. So that I've changed the configuration files (for the server and client): cxf-servlet.xml:
<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:endpoint
id="helloWorld"
implementor="service.HelloWorldImpl"
address="/HelloWorld">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
<ref bean="WSS4JInInterceptor"/>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature"/>
<entry key="passwordCallbackRef">
<ref bean="passwordCallback"/>
</entry>
<entry key="signaturePropFile" value="server_sign.properties"/>
</map>
</constructor-arg>
</bean>
<bean id="passwordCallback" class="service.PasswordCallbackHandler" />
server_sign.properties:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keyStorePassword
org.apache.ws.security.crypto.merlin.file=publicstore.jks
cxf-client-servlet.xml:
<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/schema/jaxws.xsd">
<bean id="client" class="service.HelloWorld" factory-bean="clientFactory" factory-method="create"/>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="service.HelloWorld"/>
<property name="address" value="http://localhost:8080/services/HelloWorld"/>
<property name="outInterceptors">
<list>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<ref bean="WSS4JOutInterceptor"/>
</list>
</property>
</bean>
<bean id="WSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<property name="properties">
<map>
<entry key="action" value="Signature"/>
<entry key="user" value="ws-client" />
<entry key="passwordCallbackRef">
<ref bean="passwordCallback"/>
</entry>
<entry key="signaturePropFile" value="client_sign.properties"/>
</map>
</property>
</bean>
<bean id="passwordCallback" class="client.PasswordCallbackHandler" />
The client is working perfectly. It uses it's PasswordCallbackHandler. The problem is the server doesn't seem to use its PasswordCallbackHandler. I've run the server in a debug mode, but it doesn't go to this class. Can anybody, please, explain, what do I do wrong?
Thanks in advance.
PROGRESS:
if you try to provide a request from a user, which certificate is not in the server's keystore, the error is raised ("No certificates for user ws-client1 were found for signature")
from the resource: "As you can see in the jbossws-cxf.xml file above, a keystore password callback handler is also configured; while the properties file has the password for the keystore, this callback handler is used to set password for each key (it has to match the one used when each key was imported in the store)."
Upvotes: 6
Views: 9213
Reputation: 3038
Well, after some research in the source code of wss4j I've realized, that there is no callback handler in the WSS4JInInterceptor in the case of the Signature action (only).
Upvotes: 3
Reputation: 10639
I suppose you need to add <entry key="action" value="UsernameToken Signature" />
to both server and client contexts (otherwise you have only sign action). Also for client <entry key="passwordType" value="PasswordText" />
might be necessary (I am not sure what is default: plaintext or digest, I suppose the last one).
Upvotes: 0