I'm trying to setup a CXF Service and Client using UsernameTokenSignature. Startingpoint is an existing, code first, service. Unfortunatly all examples I found use WS-Policy, which is - as I understand - not supported by CXF in a code first scenario.
I managed to create a client which sends messages like I expect using this configuration:
Client:
<jaxws:client id="clientWithUsernameTokenSignature" serviceClass="mypackage.MyServiceInterface" address="http://localhost:8081/ws-security-secured-soap-service/services/Service_v1">
<jaxws:outInterceptors>
<ref bean="WSS4JOutInterceptor_UsernameTokenSignature" />
</jaxws:outInterceptors>
</jaxws:client>
WSS4JOutInterceptor
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" id="WSS4JOutInterceptor_UsernameTokenSignature">
<constructor-arg>
<map>
<entry key="action" value="UsernameTokenSignature" />
<entry key="user" value="Admin" />
<entry key="passwordCallbackClass" value="mypackage.ClientCallbackHandler" />
</map>
</constructor-arg>
</bean>
However I failed setting up a service to process the messages from this client correctly. I tried:
Service:
<jaxws:endpoint id="soapServ_v3" implementor="#myServiceFacade" address="/MyService_v1">
<jaxws:inInterceptors>
<ref bean="WSS4JInInterceptor_UsernameTokenSignature" />
</jaxws:inInterceptors>
</jaxws:endpoint>
WSS4JInInterceptor
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="WSS4JInInterceptor_UsernameTokenSignature">
<constructor-arg>
<map>
<entry key="action" value="UsernameTokenSignature" />
<entry key="passwordCallbackClass" value="mypackage.ServerCallbackHandler" />
</map>
</constructor-arg>
</bean>
Doing this the server doesn't accept messages from the client and responds with a security error. Debugging I found that the first place it fails is in verifyUnknownPassword of org.apache.wss4j.dom.validate.UsernameTokenValidator. Here allowUsernameTokenDerivedKeys is set to false. I presume there is some configuration I can set to get this to to true.
Which is the correct configuration on the server to allow username token derived keys?
Even if I use the debugger to change the value to true the service call still fails. In that case the interceptor throws an exception at checkActions: 'An error was discovered processing the header'.
So I presume there's something else I need to configure aswell. Anyone knows how to set this up correctly?
Ok I finally figured it out. The boolean property 'allowUsernameTokenNoPassword' needs to be set to 'true' so that the server accepts a UT with no password. Then to pass the security header check additionally 'UsernameTokenNoPassword' needs to be added as action.
The working configuration looks like this:
WSS4JInInterceptor:
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="WSS4JInInterceptor_UsernameTokenSignature">
<constructor-arg>
<map>
<entry key="action" value="UsernameTokenSignature UsernameTokenNoPassword" />
<entry key="allowUsernameTokenNoPassword" value="true" />
<entry key="passwordCallbackClass" value="mypackage.ServerCallbackHandler" />
</map>
</constructor-arg>
</bean>