3
votes

I'm trying to implement a CXF Endpoint with WS-Security and receive requests sent from soapUI. The password for UsernameToken is stored in plan text. I'm only interested in receiving requests.

I'm using ServiceMix 5.0.0 with CXF 2.7.10 and Camel 2.12.3.

The policy element from the WSDL file:

  <wsp:Policy wsu:Id="MyPolicy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:TransportBinding
          xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken RequireClientCertificate="false" />
              </wsp:Policy>
            </sp:TransportToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256 />
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Lax />
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp />
          </wsp:Policy>
        </sp:TransportBinding>
        <sp:SignedSupportingTokens
          xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:UsernameToken
              sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
              <wsp:Policy>
                <sp:WssUsernameToken10 />
              </wsp:Policy>
            </sp:UsernameToken>
          </wsp:Policy>
        </sp:SignedSupportingTokens>
        <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy />
        </sp:Wss10>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

The SOAP message generated by soapUI:

<wsse:Security soapenv:mustUnderstand="1"
  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

  <wsse:UsernameToken wsu:Id="UsernameToken-0784752F597FAC191C140966645160280">
    <wsse:Username>foo</wsse:Username>
    <wsse:Password
      Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>
    <wsse:Nonce
      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">8C0iYAOWi3b+EgfDaY6n+Q==</wsse:Nonce>
    <wsu:Created>2014-09-02T14:00:51.602Z</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>

The WSS4JInInterceptor interceptor that I'm adding to the CXF Endpoint In interceptors. This is the only interceptor that I'm adding explicitly.

  private WSS4JInInterceptor getWssInInterceptor() {
    Map<String, Object> propertiesMap = new HashMap<String, Object>();
    propertiesMap.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    propertiesMap.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
    propertiesMap.put(WSHandlerConstants.USER, "bar");
    propertiesMap.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());
    return new WSS4JInInterceptor(propertiesMap);
  }

The ServerPasswordCallback.class

public class ServerPasswordCallback implements CallbackHandler {

  @Override
  public void handle(Callback[] callbacks) throws IOException,
      UnsupportedCallbackException {

    for (int i = 0; i < callbacks.length; i++) {

      WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

      if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
        if (pc.getIdentifier().equalsIgnoreCase("foo"))
          pc.setPassword("bar");
      }
    }

  }

}

I'm using soapUI to send a request to the server, but I'm getting this in the ServiceMix's log:

2014-09-02 17:00:44,630 | WARN  | qtp32763811-5522 | PhaseInterceptorChain            | ?                                   ? | 129 - org.apache.cxf.cxf-api - 2.7.10 | Interceptor for {http://localhost/incoming}MyService#{http://localhost/incoming}IncomingChannel has thrown exception, unwinding now
org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}IncludeTimestamp
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}Layout
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedSupportingTokens
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}UsernameToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}Wss10
        at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.ws.policy.PolicyVerificationInInterceptor.handle(PolicyVerificationInInterceptor.java:101)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44)[161:org.apache.cxf.cxf-rt-ws-policy:2.7.10]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[129:org.apache.cxf.cxf-api:2.7.10]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[129:org.apache.cxf.cxf-api:2.7.10]

Q:

If use the wrong credentials in the request created in soapUI I get the expected exception, that's ok, but how can this policies be satisfied on the server-side? Where can I find some documentation/examples about these policies assertions?

Thanks!

1

1 Answers

3
votes

You don't need to add the "WSS4JInInterceptor" at all. The WSS4JInInterceptor does not apply when you have a WS-SecurityPolicy. In this case, CXF takes care of setting up all of the interceptors for you. You only have to supply some configuration parameters as JAX-WS properties.

Here are some examples in spring:

https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob_plain;f=systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ut/server.xml;hb=HEAD

Typically you only need to supply a CallbackHandler ("ws-security.callback-handler") for this (UsernameToken) use-case.

BTW the request does not match the policy as it does not include a Timestamp. So either remove the "IncludeTimestamp" policy or else add one to the request in SOAP-UI.

Colm.