<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arsenalist &#187; web services</title>
	<atom:link href="http://arsenalist.com/category/web-services/feed/" rel="self" type="application/rss+xml" />
	<link>http://arsenalist.com</link>
	<description>Arsenal blog by a Canadian</description>
	<lastBuildDate>Sat, 31 Jul 2010 17:23:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>CXF WS-Security using JSR 181 + Interceptor Annotations (XFire Migration)</title>
		<link>http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/</link>
		<comments>http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 16:38:36 +0000</pubDate>
		<dc:creator>Arsenalist</dc:creator>
				<category><![CDATA[cxf]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[xfire]]></category>

		<guid isPermaLink="false">http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/</guid>
		<description><![CDATA[This post has moved here.]]></description>
			<content:encoded><![CDATA[<p><a href="http://depressedprogrammer.wordpress.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/">This post has moved here.</a></p>
<br/><fb:like href="http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/"></fb:like>]]></content:encoded>
			<wfw:commentRss>http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python client for web services using WS-Security</title>
		<link>http://arsenalist.com/2007/01/27/python-client-for-web-services-using-ws-security/</link>
		<comments>http://arsenalist.com/2007/01/27/python-client-for-web-services-using-ws-security/#comments</comments>
		<pubDate>Sat, 27 Jan 2007 01:17:08 +0000</pubDate>
		<dc:creator>Arsenalist</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://arsenalist.com/2007/01/27/python-client-for-web-services-using-ws-security/</guid>
		<description><![CDATA[Hopefully this entry serves as some decent documentation on how to write a Python client that accesses a web service which uses WS-Security. When I was trying to figure it out, Otu Ekanem&#8217;s response on the mailing list was invaluable. The example is relevant for any web service framework independent of programming language. This is [...]]]></description>
			<content:encoded><![CDATA[<p>Hopefully this entry serves as some decent documentation on how to write a Python client that accesses a web service which uses WS-Security.   When I was trying to figure it out, <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=31529787&amp;forum_id=1729">Otu Ekanem&#8217;s response on the mailing list</a> was invaluable.  The example is relevant for any web service framework independent of programming language.  This is tested with <a href="http://xfire.codehaus.org/">XFire</a> 1.2.4 but can be used with .NET or other Java web service frameworks like <a href="http://ws.apache.org/axis2/">Axis2</a>.</p>
<p>When accessing a web service which has WS-Security enabled you must send very specific headers as part of your SOAP envelope in order for the request to be processed. You can read all about the <a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf">glorious specification in PDF Format</a> if you like.   I&#8217;m using the <a href="http://pywebsvcs.sourceforge.net/">Zolera Soap Infrastructure</a> (ZSI) Library for Python which supports <a href="http://pywebsvcs.sourceforge.net/guide.html#SECTION003120000000000000000">client stub generation</a>.  Given the generated stubs, there are two ways of  adding custom headers to outgoing SOAP messages.</p>
<p><strong>Method 1 &#8211; Not desirable but worth a mention</strong></p>
<p>The first method involves modifying the generated code which is highly undesirable.  Using the very simple <a href="http://arsenalist.com/2007/01/19/php-client-for-web-services/">SportsService web service example</a>, you must modify the generated SportsService_client.py and edit the following line:</p>
<p>[sourcecode language='python']<br />
self.binding.Send(None, None,<br />
   request, soapaction=&#8221;", **kw)<br />
[/sourcecode]<br />
to read<br />
[sourcecode language='python']<br />
self.binding.Send(None, None,<br />
   request, soapaction=&#8221;", soapheaders=(obj1,obj2) )<br />
[/sourcecode]<br />
where obj1 and obj2 are instances of Python objects which are serialized as part of the SOAP header.  I found this way to be tedious as you have to design your classes to match the SOAP header and write additional serialization code.  It is also hard to create the exact header as namespaces and prefixes tend to be a problem.</p>
<p><strong>Method 2 &#8211; Probably the way to go, way more customizable </strong></p>
<p>We can use DOM-like methods to modify the SOAP header and send out exactly what we need.   The example implements the UsernameToken strategy but other ones can also be implemented by modifying the headers in a similar manner.  The generated Port class&#8217; binding attribute has a sig_handler attribute which can be assigned an instance of a custom class.   In this custom class, we must implement two methods, sign and verify, that can modify the header and check it&#8217;s validity, respectively.   The sign method takes in as argument a <a href="http://pywebsvcs.sourceforge.net/apidocs/ZSI/writer.html">SoapWriter</a> which enables us to modify the header.  So without further ado, here&#8217;s the class that adds WS-Security headers to the outgoing SOAP envelope as discussed above.  The code has been formatted and modified to fit the page.</p>
<p>[sourcecode language='python']<br />
# Deprecated in 2.5, use the hashlib module instead:<br />
#     http://docs.python.org/lib/module-hashlib.html<br />
import sha</p>
<p>import binascii<br />
import base64<br />
import time<br />
import random</p>
<p>class SignatureHandler:</p>
<p>  OASIS_PREFIX =<br />
    &#8220;http://docs.oasis-open.org/wss/2004/01/&#8221; +<br />
      &#8220;oasis-200401&#8243;</p>
<p>  SEC_NS = OASIS_PREFIX +<br />
    &#8220;-wss-wssecurity-secext-1.0.xsd&#8221;<br />
  UTIL_NS = OASIS_PREFIX +<br />
    &#8220;-wss-wssecurity-utility-1.0.xsd&#8221;<br />
  PASSWORD_DIGEST_TYPE = OASIS_PREFIX +<br />
    &#8220;-wss-username-token-profile-1.0#PasswordDigest&#8221;<br />
  PASSWORD_PLAIN_TYPE = OASIS_PREFIX +<br />
    &#8220;-wss-username-token-profile-1.0#PasswordText&#8221;</p>
<p>  def __init__(self, user, password, useDigest=False):<br />
    self._user = user<br />
    self._created = time.strftime(&#8216;%Y-%m-%dT%H:%M:%SZ&#8217;,<br />
      time.gmtime(time.time()))<br />
    self._nonce = sha.new(str(random.random())).<br />
      digest()<br />
    if (useDigest):<br />
      self._passwordType = self.PASSWORD_DIGEST_TYPE<br />
      digest = sha.new(self._nonce + self._created +<br />
        password).digest()</p>
<p>      # binascii.b2a_base64 adds a newline at the end<br />
      self._password = binascii.b2a_base64(digest)[:-1]<br />
    else:<br />
      self._passwordType = self.PASSWORD_PLAIN_TYPE<br />
      self._password = password</p>
<p>  def sign(self,soapWriter):</p>
<p>    # create  element<br />
    securityElem = soapWriter._header.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:Security&#8221;)<br />
    securityElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.SEC_NS)<br />
    securityElem.node.<br />
      setAttribute(&#8220;SOAP-ENV:mustunderstand&#8221;, &#8220;1&#8243;)</p>
<p>    # create  element<br />
    usernameTokenElem = securityElem.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:UsernameToken&#8221;)<br />
    usernameTokenElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.SEC_NS)<br />
    usernameTokenElem.node.<br />
      setAttribute(&#8220;xmlns:wsu&#8221;, self.UTIL_NS)</p>
<p>    # create  element<br />
    usernameElem = usernameTokenElem.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:Username&#8221;)<br />
    usernameElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.SEC_NS)</p>
<p>    # create  element<br />
    passwordElem = usernameTokenElem.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:Password&#8221;)<br />
    passwordElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.SEC_NS)<br />
    passwordElem.node.<br />
      setAttribute(&#8220;Type&#8221;, self._passwordType)</p>
<p>    # create  element<br />
    nonceElem = usernameTokenElem.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:Nonce&#8221;)<br />
    nonceElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.SEC_NS)</p>
<p>    # create  element<br />
    createdElem = usernameTokenElem.<br />
      createAppendElement(&#8220;&#8221;, &#8220;wsse:Created&#8221;)<br />
    createdElem.node.<br />
      setAttribute(&#8220;xmlns:wsse&#8221;, self.UTIL_NS)</p>
<p>    # put values in elements<br />
    usernameElem.<br />
      createAppendTextNode(self._user)<br />
    passwordElem.<br />
      createAppendTextNode(self._password)<br />
    # binascii.b2a_base64 adds a newline at the end<br />
    nonceElem.<br />
      createAppendTextNode(<br />
        binascii.b2a_base64(self._nonce)[:-1])<br />
    createdElem.createAppendTextNode(self._created)</p>
<p>  def verify(self,soapWriter):<br />
    self<br />
[/sourcecode]<br />
Example usage of this is:<br />
[sourcecode language='python']<br />
from SportsService_client import *<br />
from SportsService_types import *</p>
<p>locator = SportsServiceLocator()<br />
port = locator.getSportsServiceHttpPort()<br />
sigHandler = SignatureHandler(&#8220;user&#8221;, &#8220;password&#8221;, True)<br />
port.binding.sig_handler = sigHandler</p>
<p>request = getMascotRequest()<br />
teamObj = ns0.Team_Def(&#8220;Team&#8221;)<br />
teamObj._name = &#8220;toronto&#8221;<br />
request._team = teamObj</p>
<p>response = port.getMascot(request)<br />
print response._out._name<br />
[/sourcecode]<br />
As you can see the SignatureHandler class is implementing an &#8220;interface&#8221; which enables it to process outgoing SOAP Requests.  The verify method is empty but can contain code to check whether the SOAP header is valid.</p>
<p>If you would like write a PHP client that accesses a WS-Security enabled service, you should read <a href="http://www.identityblog.com/?p=598">Kim Cameron&#8217;s IdentityBlog entry</a> which has links to the source code needed.  If you simply want to use a PHP client for a non WS-Security web service, <a href="http://arsenalist.com/2007/01/19/php-client-for-web-services/">an earlier blog entry covers that</a>.</p>
<br/><fb:like href="http://arsenalist.com/2007/01/27/python-client-for-web-services-using-ws-security/"></fb:like>]]></content:encoded>
			<wfw:commentRss>http://arsenalist.com/2007/01/27/python-client-for-web-services-using-ws-security/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Writing PHP clients for XFire, Axis and .NET Web Services</title>
		<link>http://arsenalist.com/2007/01/19/php-client-for-web-services/</link>
		<comments>http://arsenalist.com/2007/01/19/php-client-for-web-services/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 02:46:01 +0000</pubDate>
		<dc:creator>Arsenalist</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://arsenalist.com/2007/01/19/php-client-for-web-services/</guid>
		<description><![CDATA[If you&#8217;re finding yourself hunting down incomplete documentation about writing a PHP client for your Java or .NET web services, you&#8217;re not alone. PHP SOAP toolkits like NuSOAP and Pear SOAP provide sub-par API&#8217;s into web service development and give a decent person a really hard time when it comes to writing clients. The best [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re finding yourself hunting down incomplete documentation about writing a PHP client for your Java or .NET web services, you&#8217;re not alone.  PHP SOAP toolkits like NuSOAP and Pear SOAP provide sub-par API&#8217;s into web service development and give a decent person a really hard time when it comes to writing clients.  The best way to go IMHO is using PHP&#8217;s built-in SOAP libraries.  The other thing to keep your eye on is <a href="http://pecl.php.net/package/axis2">Axis2 for PHP</a> which is still in Beta.  For now we&#8217;ll focus on the PHP 5 and it&#8217;s SOAP extension.  To enable the extension, your php.ini file must something like the following:</p>
<p><strong>Under Dynamic Extensions:</strong></p>
<pre>extension_dir="C:/php/ext/"
extension=php_soap.dll</pre>
<p><strong>Under Module Settings:</strong></p>
<pre>
[soap]
soap.wsdl_cache_enabled=0
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400</pre>
<p>Restart the Apache Web Server for the changes to take effect, once that is done, we are free to use the PHP Soap extensions.  This example is applicable to Java web services generated by <a href="http://xfire.codehaus.org/">XFire</a> or <a href="http://ws.apache.org/axis2/">Axis</a> or any other framework and also to .NET web services.  As long as there&#8217;s a WSDL, we&#8217;re good.   This example has been tested with XFire 1.2.4.</p>
<p>In this example there is one web service called SportsService which exposes one method: <code>public Mascot getMascot(Team team)</code></p>
<p>The method takes in as parameter a complex Java object called Team and returns a Mascot, another complex data type.   Although this example can easily use primitives, I&#8217;ve chosen to use Java objects because I want to illustrate a specific point.  The XFire Java client is fairly easy to write and a <a href="http://arsenalist.com/2007/01/18/implementing-ws-security-with-jsr181-annotations-using-wss4j-in-xfire/">previous blog entry</a> covered a similar client.  Both the Team and Mascot classes are POJO&#8217;s with one String property called name, a default constructor and getter/setter methods.  They are excluded here for brevity.</p>
<p>Before we look at the PHP client, let&#8217;s look at the relevant portion of the WSDL that is generated, mainly the types and the information about the method getMascot which we will be calling:</p>
<pre>
&lt;wsdl:types&gt;
    &lt;xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            attributeFormDefault="qualified"
            elementFormDefault="qualified"
            targetNamespace="http://vo.arsenalist.com"&gt;
        &lt;xsd:complexType name="Team"&gt;
            &lt;xsd:sequence&gt;
                &lt;xsd:element minOccurs="0"
                             name="name"
                             nillable="true"
                             type="xsd:string"/&gt;
            &lt;/xsd:sequence&gt;
        &lt;/xsd:complexType&gt;
        &lt;xsd:complexType name="Mascot"&gt;
            &lt;xsd:sequence&gt;
                &lt;xsd:element minOccurs="0"
                             name="name"
                             nillable="true"
                             type="xsd:string"/&gt;
            &lt;/xsd:sequence&gt;
        &lt;/xsd:complexType&gt;
    &lt;/xsd:schema&gt;
    &lt;xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            attributeFormDefault="qualified"
            elementFormDefault="qualified"
            targetNamespace="http://ws.arsenalist.com"&gt;
        &lt;xsd:element name="getMascot"&gt;
            &lt;xsd:complexType&gt;
                &lt;xsd:sequence&gt;
                    &lt;xsd:element maxOccurs="1"
                                 minOccurs="1"
                                 name="team"
                                 nillable="true"
                                 type="ns1:Team"/&gt;
                &lt;/xsd:sequence&gt;
            &lt;/xsd:complexType&gt;
        &lt;/xsd:element&gt;
        &lt;xsd:element name="getMascotResponse"&gt;
            &lt;xsd:complexType&gt;
                &lt;xsd:sequence&gt;
                    &lt;xsd:element maxOccurs="1"
                                 minOccurs="1"
                                 name="out"
                                 nillable="true"
                                 type="ns1:Mascot"/&gt;
                &lt;/xsd:sequence&gt;
            &lt;/xsd:complexType&gt;
        &lt;/xsd:element&gt;
    &lt;/xsd:schema&gt;
&lt;/wsdl:types&gt;</pre>
<p>Here&#8217;s the PHP client that creates a Team type, passes it to the web service which returns a Mascot type.</p>
<pre>
&lt;?php

//set up the service client using WSDL
$wsdl = "http://arsenalist.com/SportsService?wsdl";
$client = new SoapClient($wsdl);

// assign the name attribute of Team to "toronto"
$wrapper-&gt;team-&gt;name =
		new SoapVar("toronto", XSD_STRING);

// call the getMascot method
$response = $client-&gt;__soapCall("getMascot",
				    array($wrapper));

// print out the Mascot
print($response-&gt;out-&gt;name);

?&gt;</pre>
<p>The wrapper object is created out of the blue so as to pass it to the web service as the lone parameter encapsulating the Team data type.</p>
<p>By looking at the WSDL, we can determine how to &#8220;instantiate&#8221; Team and Mascot data types on the client side.  For example, to create a Team data type and assign it&#8217;s name property to &#8220;toronto&#8221;, we simply refer to it using associative array syntax and both the Team object and it&#8217;s property name are created &#8220;on the fly&#8221;.  There&#8217;s no mucking around with namespaces etc.  We&#8217;re simply wrapping the primitives inside other PHP &#8220;objects&#8221; using the same syntax as associative arrays. You can go as deep as you want in the object hierarchy in PHP without having to worry about encountering nulls because if an array element being accessed doesn&#8217;t exist, it is created for you.</p>
<p>It&#8217;s also always a good idea to use the $client-&gt;__getTypes() and do a print_r(..)  on the results to see what you are dealing with before you start communicating with a WSDL  For example, the result of a print_r($client-&gt;__getTypes()) on the above WSDL returned the following:</p>
<pre>
Array (
   [0] =&gt; struct Team { string name; }
   [1] =&gt; struct Mascot { string name; }
   [2] =&gt; struct getMascot { Team team; }
   [3] =&gt; struct getMascotResponse { Mascot out; }
)</pre>
<p>As you can see this information can be helpful when deciding how to initialize your client side variables.</p>
<p>Note that you can also use $client-&gt;getMascot($wrapper) instead of $client-&gt;__soapCall(&#8220;getMascot&#8221;, array($wrapper)).  The latter is used mostly when passing extra parameters such as SOAP headers etc.</p>
<p>This is a fairly simple example which hopefully illustrated the point that accessing web services using PHP is not a daunting task, and most of all there are no additional libraries to install as long as you&#8217;re using PHP5 and up.  If you would like write a PHP client that accesses a WS-Security enabled service, you should read <a href="http://www.identityblog.com/?p=598">Kim Cameron’s IdentityBlog entry</a> which has links to the source code needed.</p>
<br/><fb:like href="http://arsenalist.com/2007/01/19/php-client-for-web-services/"></fb:like>]]></content:encoded>
			<wfw:commentRss>http://arsenalist.com/2007/01/19/php-client-for-web-services/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
