mikeobrien.net Curriculum Vitae Blog Labs
Saturday, April 25, 2009

I have run into a couple of instances where I've had to manually add a WSS UsernameToken to consume a WCF service with the basicHttpBinding and a UsernameToken. The client could not understand the WSS timestamp returned by WCF (Notably ColdFusion/Axis1.2 w/ no wss4j). If you are trying to achieve improbability and want to just turn this off there isn't a way to disable the timestamp in the basicHttpBinding or wsHttpBinding through configuration but you can use the customBinding. To emulate basicHttpBinding with transport security and message credentials but with the timestamp off you can define the custom binding as follows:

...
<bindings>
  <customBinding>
    <binding name="MyBinding">
      <security authenticationMode="UserNameOverTransport" includeTimestamp="false" />
      <textMessageEncoding messageVersion="Soap11" />
      <httpsTransport />
    </binding>
  </customBinding>
</bindings>
...
Saturday, April 25, 2009 3:28:30 AM (GMT Daylight Time, UTC+01:00)  #   |  Comments [0]  |  Trackback

The following demonstrates how to consume a web service that requires a WSS UsernameToke with ColdFusion:

<html>
<head><title>My Web Services</title></head>
<body>
<h2>My Web Services</h2>

<cfscript>

service = createObject("webservice", "https://services.nsa.gov/NOCList.svc?wsdl");

AddCredentials(service, "username", "p@$$w0rd");

result = service.DoSomething();

writeoutput("Result=" & result);

function AddCredentials(service, username, password)
{
      wssNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
      header = createObject("java", "org.apache.axis.message.SOAPHeaderElement");
      header.init(wssNamespace, "wsse:Security");
      header.addChildElement("wsse:UsernameToken");
      header.getFirstChild().addChildElement("wsse:Username").setValue(username);
      header.getFirstChild().addChildElement("wsse:Password").setValue(password);
      header.setMustUnderstand(1);
      service.setHeader(header);
}

</cfscript>

</body>
</html>
Saturday, April 25, 2009 3:09:03 AM (GMT Daylight Time, UTC+01:00)  #   |  Comments [0]  |  Trackback
Friday, April 24, 2009

The following are a couple of things I've discovered about web service namespaces while working on interoperability:

1) If your not going to use a URL for your namespace you need to prepend your namespace with a uri scheme (IE: "myscheme:MyNamespace") to signify that it is absolute. The urn scheme is an appropriate choice but this isn't required as the namespace must simply be a URI. The Microsoft stacks don't seem to mind if the scheme is not present but the Apache Xml Security library is finicky about this (Thinking its a relative namespace if its not there), you will see the following error on the client side if you don't:

org.apache.xml.security.c14n.CanonicalizationException: Element ns1:doSomething has a relative namespace: xmlns:ns1="MyNamespace"

2) Use the same namespace for your binding namespace, behavior namespace, and all service and data contract namespaces. WCF will break out WSDL artifacts from different namespaces into different files and some proxy generators don't like this (Notably ColdFusion).

Friday, April 24, 2009 8:09:06 PM (GMT Daylight Time, UTC+01:00)  #   |  Comments [0]  |  Trackback
Creative Commons License