Calling the Web21C SDK SOAP Services Directly
We provide software to call the SDK services from a variety of programming languages. However you may still want to develop your own SDK. This page provides some minimal guidance for calling the Web21C services directly.
Registration
Before calling the services you need to be registered with the SDK. Having registered yourself, you can then register one or more applications for which you will be given an X.509 certificate for your application.
Services
The set of services currently exposed includes:
| Service | Version | Policy |
|---|---|---|
| MessagingOneWay | 2007/07 | CommonCapabilityPolicy |
| SessionThirdPartyCall | 2007/07 | CommonCapabilityPolicy |
| SessionConferencing | 2007/07 | CommonCapabilityPolicy |
| WhiteLabelAuthentication | 2007/01 | WLAPolicy |
| MessagingInbound | 2007/07 | CommonCapabilityPolicy |
Endpoints
Each SDK service is publicly available on a pair of endpoints - "Sandbox" and "Production". The endpoint to which the SOAP messages are HTTP POST'ed is constructed as follows:
https://{host}/endpoint/{Service}/{Version}
Where the values are taken from the Services table and the {host} is either:
| Environment | Host |
|---|---|
| Sandbox: | acorn.ws.bt.com |
| Production: | oaktree.ws.bt.com |
For example, the current production endpoint for Messaging/OneWay is:
https://oaktree.ws.bt.com/endpoint/Messaging/OneWay/2007/07
Note, a different certificate is required for the Production endpoint to the Sandbox.
Policy
Services with a CommonCapabilityPolicy or WLAPolicy require signed SOAP messages to be sent to an endpoint as described by the WSDL and the headers described in this document.
SOAP Message Elements
/soap:Envelope
The SOAP message uses a few different namespaces, it's a matter of style, but here they are all declared on the soap envelope rather than on individual elements inside the message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sdk="http://sdk.bt.com/2007/07/Messaging/OneWay"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
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"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<soap:Header ..
<soap:Body ..
</soap:Envelope>
The actual prefixes used aren't critical. Note the sdk namespace is service specific
and matches the Schema targetNamespace of the XML element references in the
WSDL:
<xs:schema targetNamespace="http://sdk.bt.com/2007/07/Messaging/OneWay">
/soap:Envelope/soap:Header
Next comes the SOAP header. Note the order of the headers isn't significant:
<soap:Header> <wsa:MessageID .. <wsa:Action .. <wsse:Security .. </soap:Header>
/soap:Envelope/soap:Body
Finally, the SOAP Body contains data entirely dependent upon the operation:
<soap:Body wsu:Id="BodyID"> <sdk:sendMessage> <sdk:recipientUris> <sdk:uri>easysms:arrived</sdk:uri> <sdk:recipientUris> <sdk:from>From</sdk:from> <sdk:messageText>A test message</sdk:messageText> </sdk:sendMessage> </soap:Body>
Note, the soap:Body element has a wsu:Id attritbute,
this is referenced by the digital signature inside the wsse:Security header.
The Body contents are defined by the XML Schema in the WSDL, for example:
<xs:element name="sendMessage">
<xs:complexType>
<xs:sequence>
<xs:element name="recipientUris" type="sdk:Uris"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="messageText" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
soap:Header/wsa:MessageID
The WS-Addressing wsa:MessageID value be a URI value, and shouldn't be reused in subsequent messages. A RFC4122 UUID is ideal:
<wsa:MessageID>urn:uuid:da74afd9-a98c-ca56-4275-9fb601cfb6ae</wsa:MessageID>
soap:Header/wsa:Action
The WS-Addressing wsa:Action is used to dispatch the message to appropriate
operation:
<wsa:Action>http://sdk.bt.com/2007/07/Messaging/OneWay#sendMessage</wsa:Action>
The contents are the same as the HTTP SOAPAction value defined for the operation in the WSDL SOAP binding,
in this case sendMessage:
<wsdl:operation name="sendMessage"> <wsoap:operation soapAction="http://sdk.bt.com/2007/07/Messaging/OneWay#sendMessage"/>
soap:Header/wsse:Security
The WS-Security wsse:Security header is a bag containing:
<wsse:Security> <ds:Signature .. <wsu:Timestamp .. <wsse:BinarySecurityToken .. </wsse:Security>
wsse:Security/ds:Signature
The ds:Signature element contains information on which
parts of the message have been signed, the calculated signature value,
and the key used to generate the signature:
<ds:Signature> <ds:SignedInfo .. <ds:SignatureValue .. <ds:KeyInfo .. </ds:Signature>
wsse:Security/ds:Signature/ds:SignedInfo
The ds:SignedInfo element identifies the elements within the message
digitally signed . Signing does present something of a challenge:
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
</ds:SignatureMethod>
<ds:Reference ..
</ds:Reference>
wsse:Security/ds:Signature/ds:Reference*
There's one ds:Reference element for each XML element signed, which includes a SHA1
hash of the canonicalized XML.
The URI attribute is an IDREF to the wsu:Id
<ds:Reference URI="#TimestampID"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"> </ds:DigestMethod> <ds:DigestValue>SiiPT7TtOnDw4vBPOVvS0YfP4pw=</ds:DigestValue> <ds:Reference>
<ds:Reference URI="#BodyID""> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"> </ds:DigestMethod> <ds:DigestValue>X23PT7TtOnDw4vBPOViuiixoEfp=</ds:DigestValue> <ds:Reference>
wsse:Security/ds:Signature/ds:SignatureValue
<ds:SignatureValue>NE5rWsMqCz0..V8IPgyQfE70Ag9eolhUoX9SSj/=</ds:SignatureValue>
wsse:Security/ds:Signature/ds:KeyInfo
ds:KeyInfo is a reference to the X.509 certifcate serialized in wsse:BinarySecurityToken:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#CertID"></wsse:Reference>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
wsse:Security/wsu:Timestamp
The wsu:Timestamp element contains wsu:Created and wsu:Expires times in RFC3339 format.
Note for the timestamp elements order is significant:
<wsu:Timestamp wsu:Id="TimestampID"> <wsu:Created>2007-02-23T07:47:02Z</wsu:Created> <wsu:Expires>2007-02-23T08:47:02Z</wsu:Expires> </wsu:Timestamp>
wsse:Security/wsse:BinarySecurityToken
The final part of the wsse:Security element is the public X.509 certificate
registered with BT for the application. The binary token is serialized as a Base64 encoded string inside a wsse:BinarySecurityToken element:
<wsse:BinarySecurityToken EncodingType= "http://docs.oasis-open.org/wss/2004/01 /oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType= "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertID">MIICdzCCAeCgAwIBAgI.. ..RUAEeyHeZhdFil8trzyJv1VzgPIjDRZmhnpItzQ8= </wsse:BinarySecurityToken>
Canonicalized XML
Signed portions of the SOAP message are first serialized as canonical XML, it's supported by most DOM serializers, though in some cases as an option:
- The document is encoded in UTF-8
- line breaks are normalized to "
"
- Attribute values are normalized, default attributes are added to each element, as if by a validating processor
- where possible, character and parsed entity references are replaced with the literal characters
- CDATA sections are replaced with their literal character content
- Special characters in attribute values and character content are replaced by character references (as usual for well-formed XML)
- the XML declaration and DTD are removed
- elements always have a separatre end tag
- whitespace outside of the document element and within start and end tags is normalized
- whitespace in character content is retained apart from characters removed during line feed normalization
- attribute values are delimited using double quotes
- unused namespace declarations are removed from each element
- namespace declarations and attributes are sorted
Example
If you have got this far you probably want an example to look at.
