Unstable Terrain

Software development in the real world

Axis2 MustUnderstand shenanigans

with 4 comments

Am integrating with a .NET web service with Axis2 as the client. The web service uses WSSE so I hooked up Rampart to do the security tokens (an exercise in itself). However, Axis2 still complained when it receives the SOAP response, with

Must Understand check failed for header http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd

Rampart definitely could handle that namespace; heck, it had just sent a security token in that namespace. So what was going on?

Turns out Rampart kinda only handles stuff it expects. The response sent this as a SOAP header:

<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="_0">
        <u:Created>2010-02-19T00:05:06.259Z</u:Created>
        <u:Expires>2010-02-19T00:10:06.259Z</u:Expires>
      </u:Timestamp>
    </o:Security>

…but Rampart had only been configured to send and expect a UsernameToken in its policy.xml.

Solution: add

<sp:IncludeTimestamp />

to policy.xml and voila, Rampart is happy again.

Advertisements

Written by Trent

February 19, 2010 at 10:23 am

4 Responses

Subscribe to comments with RSS.

  1. I have identical symptoms with an AXIS2 client receieving a message from a *.Net server.

    I tried the suggested remedy, but it has no effect. Could you post the entire policy file? Is there something else required in addtion?

    Mike Pettigrew

    July 6, 2011 at 1:30 am

    • Unfortunately, I don’t have access to the policy file any more, since it was with a previous employer.

      Trent

      July 14, 2011 at 4:44 pm

  2. We never could find a policy file that solved this problem. I would still like to find one.

    Here is a solution that we did find.

    This problem was solved by setting the rampart INFLOW_SECURITY parameter with the Timestamp item. For some reason this would not work from the module.xml file in rampart.mar, so we did it programmatically as in the following code snippet.

    This solution was validated on AXIS2 version 1.5.4 and RAMPART version1.5

    Note: the password callback class was not used and references to it are commented out in the snippet.

    =================== Code snippet =======================================

    /**
    * Setup WS-Security to secure the service.
    *
    * Remember that “rampart.mar” must be in your class path to engage rampart
    */
    private void secureService(ServiceClient client) throws AxisFault {
    AxisService service = client.getAxisService();
    Options options = client.getOptions();
    String filePath = “policy.xml”;
    Policy securityPolicy = loadPolicy(filePath);
    if (securityPolicy != null) {
    options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
    securityPolicy);
    log.debug(“Security policy was found and set. See file – ”
    + filePath);
    } else {
    log.debug(“Security policy was not used”);
    }
    options.setUserName(GATEWAY_USER_ID);
    options.setPassword(GATEWAY_PASSWORD);
    client.engageModule(“rampart”);
    Options opt = client.getOptions();
    Parameter parm = getInflowConfiguration(“Timestamp”);

    opt.setProperty(WSSHandlerConstants.INFLOW_SECURITY, parm);
    }

    private Parameter getInflowConfiguration(String item) {
    InflowConfiguration ifc = new InflowConfiguration();
    //set the action item
    ifc.setActionItems(item);
    //set the password callback class
    //ifc.setPasswordCallbackClass(“axis2.adb.sync.rampart.callbackhandler.PWCBHandler”);
    //set the property file; remember if the properties is not in classpath then it will not find this.
    //ifc.setDecryptionPropFile(“client.properties”);
    //return the parameter
    return ifc.getProperty();

    }

    private Policy loadPolicy(String name) {

    InputStream resource = this.getClass().getResourceAsStream(name);
    if (resource == null) {
    log.warn(“Security policy file not found – ” + name);
    return null;
    }
    StAXOMBuilder builder;
    try {
    builder = new StAXOMBuilder(resource);
    } catch (XMLStreamException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return null;
    }
    return PolicyEngine.getPolicy(builder.getDocumentElement());
    }

    Mike Pettigrew

    July 14, 2011 at 4:52 am

    • I remember a hack we needed to do with Axis2 around the 1.4.x days, injecting a MessageContext into the method signature of the generated client stub operations so we could provide it as a parameter instead of using the field.

      While it was good that we could do so, it was annoying that we had to. Your situation appears similar in tone.

      Trent

      July 14, 2011 at 4:56 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: