Web services use SOAP faults to report fault cases back to clients. The faults can be generated from the SOAP framework in a case of invalid SOAP messages, invalid security tokens or they can be generated from the service business logic itself. The fault messages may contain simply a string indicating the error, or it may contain lot of details which could be useful to the clients find the problem. In fact the format of the SOAP fault is a standard. But services can send custom details within the details element in a SOAP fault.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Sender</faultcode>
         <faultstring>..</faultstring>
         <detail> You Custom Message </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

And you can define the schema of your custom fault message in a WSDL, so the clients can prepare to handle fault scenarios. In facts tools like Apache Axis2 WSDL2C, WSDL2Java tool will help you to work with custom faults when they are defined in the WSDL.  Here is an example section of a WSDL with an operation which can throw two faults “MyFirstException”, “MySecondException”.

<!-- fault schemas -->
<types>
 <schema ..>
  <element name="MyFirstException">
   <complexType>
    <sequence>
     <element name="text" type="xsd:string"/>
    </sequence>
   </complexType>
  </element>
  <!-- fault element -->
  <element name="MySecondException">
   <complexType>
    <sequence>
     <element name="number" type="xsd:int"/>
    </sequence>
   </complexType>
  </element>
 </schema>
</types>

<!-- the fault messages -->
<message name="MySecondExceptionFault">
 <part name="fault" element="ns1:MySecondException"/>
</message>

<message name="MyFirstExceptionFault">
 <part name="fault" element="ns1:MyFirstException"/>
</message>

<!-- operation to throw fault -->
<portType name="MyType">
 <operation name="myOperation">
  <input message="tns:myOperationRequest"/>
  <output message="tns:myOperationResponse"/>
  <fault name="MySecondException" message="tns:MySecondExceptionFault"/>
  <fault name="MyFirstException" message="tns:MyFirstExceptionFault"/>
 </operation>
</portType>

Note that the operation “myOperation” is throwing faults “MyFirstException”, “MySecondExcpetion”. If you generate the Java code for this operation, it would be simple as this,

public MyOperationRequest
MyOperation(MyOperationRequest) throws
          MyFirstExcpetion,
          MySecondExcpetion {
  // here is your business logic
}

Anyway we are going to write codes in ‘C’ language, which doesn’t have similar exception mechanism. Let see how we can do it, starting with writing the service and then writing a client.

Writing Services With Custom SOAP Faults

Once you generate the ‘C’ codes for the WSDL using WSDL2C tool, you should first have a look at the skeleton header file.

    /**
     * the generated fault union for operation "myOperation|urn:myuri:1.0",
     * in a case you want to return a fault, put the appropriate adb object for
     * the union variable pointer comes as the last parameter of the method
     */
    typedef union
    {
        adb_MyFirstException_t* MyFirstException;
        adb_MySecondException_t* MySecondException;

    } axis2_skel_MyService_myOperation_fault;

    /**
     * auto generated function declaration
     * for "myOperation|urn:myuri:1.0" operation.
     * @param env environment ( mandatory)
     * @param _myOperation of the adb_myOperation_t*
     *
     * @return adb_myOperationResponse_t*
     */
    adb_myOperationResponse_t* axis2_skel_MyService_myOperation(const axutil_env_t *env,
                                      adb_myOperation_t* _myOperation,
                                      axis2_skel_MyService_myOperation_fault *fault);

And at the very end of the header file, you will see an enumeration of constants corresponding to each fault is generated.

    typedef enum
    {
        AXIS2_SKEL_MYSERVICE_ERROR_NONE = AXIS2_SKEL_MYSERVICE_ERROR_CODES_START,

        AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
        AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,

        AXIS2_SKEL_MYSERVICE_ERROR_LAST

    } axis2_skel_MyService_error_codes;

That’s all you need to aware of. The plan is whenever you need to report the fault, you have to do three things inside the business logic.

  1. Create the adb object for the fault, in this case either “adb_MyFirstException_t” or “adb_MySecondException_t” and set it to the fault pointer variable.
  2. Set the constant corresponding to the fault using “AXIS2_ERROR_SET” function
  3. return NULL

Here is an example how you do it inside the actual business logic code.

    adb_myOperationResponse_t* axis2_skel_MyService_myOperation(const axutil_env_t *env,
                                      adb_myOperation_t* myOperation,
                                      axis2_skel_MyService_myOperation_fault *fault )
    {
        /* the buisness logic */

        ....

        if(/* checking some condition to throw the "MyFirstException" fault */)
        {
          /* 1. Creating the adb object and set it to the fault pointer variable */
          adb_MyFirstException_t *exp = NULL;
          exp = adb_MyFirstException_create(env);
          adb_MyFirstException_set_text(exp, env, "this is the exception 1"); /* custom value */

          fault->MyFirstException = exp;

          /* 2. Setting the error constant corrosponding to the fault */
          AXIS2_ERROR_SET(env->error,
                      AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
                      AXIS2_FAILURE);

          /* 3. Returning NULL */
          return NULL;
        }

        else if(/* checking some condition to throw the "MySecondException" fault */)
        {
          /* 1. Creating the adb object and set it to the fault pointer variable */
          adb_MySecondException_t *exp = NULL;
          exp = adb_MySecondException_create(env);
          adb_MySecondException_set_number(exp, env, 2);/* custom value */

          fault->MySecondException = exp;

          /* 2. Setting the error constant corrosponding to the fault */
          AXIS2_ERROR_SET(env->error,
                      AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,
                      AXIS2_FAILURE);
          /* 3. Returning NULL */
          return NULL;
        }

        /* return the response in no fault scenario */
        return response;
    }

That’s all you have to do, Axis2/C will make sure to build the fault and put your custom message inside the details element.

Writing Clients to Handle custom SOAP Faults

After generating the code for clients using WSDL2C tool, this time you should look at the generated stub header file first. It is just similar to the skeleton header files may be except all the “skel” prefixes are renamed to “stub” and additional parameter “stub” for the operation.

    /**
     * the generated fault union for operation "myOperation|urn:myuri:1.0",
     * in a case the server return a fault, the corresponding adb object will be loaded for
     * the union variable pointer comes as the last parameter of the method
     */
    typedef union
    {
        adb_MyFirstException_t* MyFirstException;
        adb_MySecondException_t* MySecondException;

    } axis2_stub_MyService_myOperation_fault;

    /**
     * auto generated function declaration
     * for "myOperation|urn:myuri:1.0" operation.
     * @param env environment ( mandatory)
     * @param _myOperation of the adb_myOperation_t*
     *
     * @return adb_myOperationResponse_t*
     */
    adb_myOperationResponse_t* axis2_stub_MyService_myOperation(axis2_stub_t* stub, const axutil_env_t *env,
                                      adb_myOperation_t* _myOperation,
                                      axis2_stub_MyService_myOperation_fault *fault);

    typedef enum
    {
        AXIS2_STUB_MYSERVICE_ERROR_NONE = AXIS2_STUB_MYSERVICE_ERROR_CODES_START,

        AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
        AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,

        AXIS2_STUB_MYSERVICE_ERROR_LAST

    } axis2_stub_MyService_error_codes;

Looking at this, you may have got the idea how to differentiate what fault is being thrown by the server and how to extract the parameters of the custom fault. Here is an example client code correctly handling exceptions.

    /* the structure to keep the fault */
    axis2_stub_MyService_myOperation_fault fault;

    ..... /* the part preparing the request is ignored here */

    /* invoking the "myOperation" operation */
    response = axis2_stub_op_MyService_myOperation(stub, env, op, &fault);

    /* checking the response == NULL implies fault is sent  */
    if(response == NULL)
    {
        /* getting the error number to distinguish the fault */
        error_code = env->error->error_number;

        /* compare error code with constants of each faults */
        if(error_code == AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION) {

            /* extracting out the adb objects */
            axis2_char_t *text = adb_MyFirstException_get_text(fault.MyFirstException, env);

            /* do a printf of the message */
            printf("My First Exception called: with param %s\\n", text);

        }
        else if(error_code == AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION) {
            /* extracting out the adb objects */
            int number = adb_MySecondException_get_number(fault.MySecondException, env);

            /* do a printf of the message */
            printf("My Second Exception called: with param %d\\n", number);

        }

    }

Note that this feature is available only in the very latest WSDL2C tool. Try to get latest build from Axis2/Java to use this up to date tool.

You can download the WSDL and codes used in this example from here, https://issues.apache.org/jira/secure/attachment/12399724/case45.zip

Now you can view the article I wrote titling “Introduction to PHP Data Services“. There I explain how you can design and implement Data Services in PHP using WSF/PHP Data Services Library.

This article covers,

  1. Designing your Data Service API.
  2. Writing the Data Service.
  3. Deploying and Testing Data Service.
  4. Make the Data Service available in both SOAP and RESTful form.
  5. Use of WS-* features in your Data Service.

If you are thinking of adapting SOA in to your database backed PHP applications, this article will be a good starting point.

If you are a web developer, you may have found many occasions you have to create simple mashups for your web site. There you call web services or data services to fill the content of the web page. Most of the time we call web services from a server side script, since there are many server side technologies like Java, PHP, .NET support web services.

But sometime it is in vain that you call your server scripts for a simple web service request. In fact You can use the famous XMLHttpRequest object to do the same thing from the client side itself. But you may need to prepare the complete SOAP envelope (Yea with SOAP headers, if required) in your hand to send it through XMLHttpRequest.

Another option is to  use the WSRequest script (http://mooshup.com/js/wso2/WSRequest.js). We normally use this script in the WSO2 Mashup Server to call the mashups designed in the serverside using stub. (The server side mashup is also mostly written in Javascript). We can use this script stand alone to call remote web services as well.

It introduce you the WSRequest class. It is exactly similar to the famous XMLHttpRequest class we used in  AJAX. In stead of plain message over HTTP like in the case of XMLHttpRequest, WSRequest send and receive messages in SOAP form. Here is its API in brief.

var WSRequest = function() {
    //----------------------------------------------------
    // the public properties - equivalent to XMLHTTPRequest
    //-----------------------------------------------------
    this.readyState = 0;
    this.responseText = null;
    this.responseXML = null;
    this.error = null;  // equivalent to httpErrorCode
    this.onreadystatechange = null;
    this.proxyAddress = null;
    this.proxyEngagedCallback = null
}

//----------------------------------------------------
// the public operations - equivalent to XMLHTTPRequest
//-----------------------------------------------------

/**
 * @description Prepare a Web Service Request .
 * @method open
 * @param {hash} options,
 *   possible options: possible values for the option
 *            useSOAP : false/true/1.1/1.2
 *            useWSA : true/false/1.0/submission
 *            useWSS : true/false (only for usernametoken & timestamp)
 *
 * @param {string} URL
 * @param {boolean} asyncFlag
 * @param {string} username
 * @param {string} password
 */
WSRequest.prototype.open = function(options, URL, asnycFlag, username, password) {.. }

/**
 * @description Send the payload to the Web Service.
 * @method send
 * @param {dom} response xml payload
 */
WSRequest.prototype.send = function(payload) {.. }

I wrote a simple javascript/html demo which calls the data service that I published for my blog. This service is written using WSF/PHP Data Services. Check the demo and client, service sources  from the following links.

AJAX Tag Search Demo | WSDL | Client | Service Demonstrates how you use SOAP Data Services using WSRequest object to retrieve the data asynchronously from javascript

There You can see, how easy to write an AJAX like page for call web services using the WSRequest javascript class.

Last week I wrote a how to on Writing a SOAP and REST Service with PHP. It shows how to write a single script that enables the SOAP and REST web services interfaces using WSF/PHP. Today I’m going to show you how you can use WSF/PHP to write clients in both SOAP and REST form.

For that I use the Amazon Client Demo hosted in the PHP Web Services Demo Site. With this demo you can do shopping with Amazon using their web services API. It uses a php library (AmazonClient.php) that allows us to connect Amazon using SOAP or REST libraries.

You can see in the library code It is using different values for “useSOAP” argument depending on what form of messaging we like to use. Amazon SOAP service uses the SOAP 1.1 and the REST service uses the “GET” HTTP method for messaging. We can configure these details as mentioned in the following table.

REST SOAP
array(
      "to"=>self::AMAZON_REST_ENDPOINT,
      "HTTPMethod"=>"GET",
      "useSOAP" => FALSE)
array(
      "to"=>self::AMAZON_SOAP_ENDPOINT,
      "useSOAP" => "1.1",
      "action" => "http://soap.amazon.com")

Since Amazon requires different request messages for SOAP and REST services, we have to create them separately depending on the request type. But the response returns by the service is same in both cases so we can handle it using the same code.

Here is how ItemLookup operation of the Amazon service is written within the above mentioned constrains.

    /**
     * ItemLookup
     * @param $ASIN Amaxon Item Id
     * @return associate array consist of the response parameters
     */
    public function ItemLookup($ASIN)
    {

        if($this->is_soap)
        {
             $req_payload = <<<XML
                <ItemLookup xmlns="http://webservices.amazon.com/AWSECommerceService/2007-10-29">
                    <SubscriptionId>{$this->amazon_key}</SubscriptionId>
                    <ResponseGroup>Medium</ResponseGroup>
                    <Request>
                        <ItemId>{$ASIN}</ItemId>
                        <ReviewPage>1</ReviewPage>
                    </Request>
                </ItemLookup>
XML;
        }
        else
        {
             $req_payload = <<<XML
                <ItemLookup xmlns="http://webservices.amazon.com/AWSECommerceService/2007-10-29">
                    <SubscriptionId>{$this->amazon_key}</SubscriptionId>
                    <Service>AWSECommerceService</Service>
                    <ResponseGroup>Large</ResponseGroup>
                    <Operation>ItemLookup</Operation>
                    <ItemId>{$ASIN}</ItemId>
                    <ReviewPage>1</ReviewPage>
                </ItemLookup>
XML;
        }

        $ret_message = $this->request($req_payload);

        $simplexml = new SimpleXMLElement($ret_message->str);

        $res = $simplexml;

        return $res;
    }

WSF/PHP enables you to write both REST and SOAP services in PHP from a single script. I have written about how you can expose your Database as a REST and SOAP services in few of my previous posts using the Data Service capability of WSF/PHP. But there can be situations where your service is not based on a Database. For an example it can use results of some calculations, or a mashup calling other services. In that case you will prefer to write the service logic yourself. Here is how you can do it.

Lets think we have weather forecast data (may be from another service) and I want to make a web service using it and make it accessible via both REST and SOAP protocols.

In our demo service we give forecasts of temperature, humidity and some other parameters for a given date. So I expect

SOAP request payload as following.

<weatherReport>
  <date>{date}</date>
  <parameter>{parameter}</parameter>
</weatherReport>

And REST Request will be like

weatherReport/{date}/forecast/{parameter}

Note that here parameter can hold values like temperature, humidity or sunset-time.

First we declare our operation and the REST Request Mapping like this,

$operations = array("weatherReport" => "weather_report");
$restmap = array("weatherReport" =>
				array("HTTPMethod" =>"GET",
				      "RESTLocation" => "weatherReport/{date}/forecast/{parameter}"));

When you declare your rest mapping like above , in the service operation you will have the same request XML for both SOAP and REST form like this,

<weatherReport>
  <date>{date}</date>
  <parameter>{parameter}</parameter>
</weatherReport>

So in your service logic you just handling the request in only above format. You can easily extract out the request parameters using SimpleXML functions and return the corresponding result. So you service operation would be something like this,

function weather_report($in_message) {

	// create the simple xml element for the request xml
	$request_xml = new SimpleXMLElement($in_message->str);

	// extract out the parameter and the date
	$date = $request_xml->date;
	$parameter = $request_xml->parameter;

	// It is up to you to retrun the weather data ($result) for the requested date and parameter

	return "<response>$result</response>";
}

Finally you create the WSService object with the “operations” and “RESTMapping” and call its reply method which actually response to the requests.

$service = new WSService(array("operations" => $operations, "RESTMapping" => $restmap));
$service->reply();

You just created a web service which will handle both SOAP and REST requests.

Yesterday’s blog on “Using Username token in Authentication” I explained a standard way of authenting SOAP messages in Application layer (Message level Authentication). Anyway you can authenticate SOAP messages in transport level itself. For an example with HTTP Transport we can use the HTTP Basic Authentication for this purpose.

Setting up a client with Authentication Information

With WSF/PHP you can give the username, password and the authentication type as options for WSClient constructor.

	$client = new WSClient(array ("to" => "http://server/myendpoint",
		"httpAuthUsername" => "user",
		"httpAuthPassword" => "user_password",
		"httpAuthType" => "basic"));

Setting up the Server to Handle the Authentication

Since the Http authentication is handled by the transport level, you have to configure your authentication information in your web server itself. (e.g. Apache or IIS).

If you are using Apache, please use this guide to configure your allowed list to access the server.

SOAP Headers are used in many WS-* standards (for an example WS-Security) to transmit information related to the QOS aspects of the service. So only the SOAP engines which process these QOS parameters are supposed to see these headers. Web Service Developer or Consumer need to care only what is in the SOAP payload (which is what inside the SOAP body element) and not SOAP headers.

But that is theory, In practice we see many places where people uses SOAP headers to transmit what they should have easily sent through SOAP Body. And many SOAP stacks also provide APIs to allow people to send/receive custom headers and standards like WSDL too provide ways to describe services which accept custom headers. So I thought it might worth to discuss how you describe custom headers in a service from a WSDL and how you can consume and serve in real world with SOAP stacks like Axis2/C and WSF/PHP.

In a WSDL 1.1 you first declare your headers in the binding section itself which is the section that is used to provide the messaging and transport protocol information.

  <binding name="RetHeaderBinding" type="tns:RetHeaderPortType">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="echoString">
      <soap:operation soapAction="http://soapinterop.org/" style="document"/>
      <input>
        <soap:body use="literal"/>
        <soap:header message="tns:Header1" part="Header1" use="literal"/>
        <soap:header message="tns:Header2" part="Header2" use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
        <soap:header message="tns:Header1" part="Header1" use="literal"/>
        <soap:header message="tns:Header2" part="Header2" use="literal"/>
      </output>
    </operation>
  </binding>

There you can see we have Header1 and Header2 in both in input and output of the operation. It refers to the message section with the specific part name that represent the header. Here is how message section will look like.

  <message name="Header1">
    <part name="Header1" element="types:Header1"/>
  </message>
  <message name="Header2">
    <part name="Header2" element="types:Header2"/>
  </message>

In this section it refers to the schema element that actually describe the element structure/schema. Here I put a string and an int in each header.

  <s:element name="Header1">
      <s:complexType>
        <s:sequence>
          <s:element name="string" type="s:string"/>
          <s:element name="int" type="s:int"/>
        </s:sequence>
      </s:complexType>
  </s:element>
  <s:element name="Header2">
      <s:complexType>
        <s:sequence>
          <s:element name="int" type="s:int"/>
          <s:element name="string" type="s:string"/>
        </s:sequence>
      </s:complexType>
  </s:element>

Here is a valid SOAP message for the WSDL description.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <ns1:Header1 xmlns:ns1="http://soapinterop.org/xsd">
         <ns1:string>test1</ns1:string>
         <ns1:int>5</ns1:int>
      </ns1:Header1>
      <ns1:Header2 xmlns:ns1="http://soapinterop.org/xsd">
         <ns1:int>8</ns1:int>
         <ns1:string>test2</ns1:string>
      </ns1:Header2>
   </soapenv:Header>
   <soapenv:Body>
      My payload
   </soapenv:Body>
</soapenv:Envelope>

If you are using Apache Axis2/C WSDL2C Codegen tool (which is shipped with Axis2/Java) you will be able to directly use the API provided with the generated code to deal with custom headers. Here is how the client API is generated for the above WSDL.

         /**
          * auto generated method signature
          * for "echoString|http://ws.dimuthu.org/blog/headers" operation.
          *
          * @param _echoStringParam
          * @param _header1
          * @param _header2
          *
          * @param dp_header10 - output header
          * @param dp_header21 - output header
          * @return adb_echoStringReturn_t*
          */
         adb_echoStringReturn_t*
         axis2_stub_op_RetHeaderService_echoString( axis2_stub_t *stub, const axutil_env_t *env,
                                              adb_echoStringParam_t* _echoStringParam,
                                              adb_Header1E0_t* _header1,
                                              adb_Header2E1_t* _header2,
                                              adb_Header1E0_t** dp_header10 /* output header double ptr*/,
                                              adb_Header2E1_t** dp_header21 /* output header double ptr*/)

Note that the first parameter is the environment variable passed in every function in Axis2/c. The second parameters is the payload. Input headers (input headers for server side) are in 3rd and 4th parameters, you can build them similar to how you build payload object. 5th and 6th are for the output headers which you only need to provide some pointers and the generated code will build you the objects from the response data.

You service will also have a similar API. There you have to create adb objects for output headers (like you build output payload) and assign the pointer to these output header double pointers.

             adb_Header2_t* arg_Header1 = adb_Header1_create(env);
             adb_Header1_set_string(arg_Header1, env, "I m response Header 1");
             adb_Header1_set_int(arg_Header1, env, 1);
             adb_Header10_t* _header1 = adb_Header10_create(env);
             adb_Header10_set_Header1(_header1, env, arg_Header1);
             *dp_header10 = _header1;

Now how about PHP, can you provide the same API form the PHP as well. Yes, PHP has references similar to C pointers. WSF/PHP already have the custom headers support in the SVN and to be released with the 2.0.
Here is the generated API for the service business logic for the above WSDL.

/**
 * Service function echoString
 * @param string $input
 * @param object of Header1 $header_in0 input header
 * @param object of Header2 $header_in1 input header
 * @param reference object of Header1 $header_out0 output header
 * @param reference object of Header2 $header_out1 output header
 * @return string
 */
function echoString($input, $header_in0, $header_in1, &$header_out0, &$header_out1) {

...
}

These tool provides APIs to consume and provide data through custom headers in same easiness you send the data in the payload. Anyway it is really recommended to not to use custom SOAP headers in your Service and try to avoid them as much as possible. Whenever you think there is valid reason to put a custom header (it is relevant to QOS aspects), just try to integrate the header processing logic to the SOAP engine. In Axis2 C or Java you can write Axis2 modules for that. That will really speed up the processing of your service and give consumers a well-designed API.

When you are developing a Web Service, you have to think about the security aspects of your service seriously. When it comes to security in web services you have two basic choices.

  1. Transport level security – Just SOAP over HTTPS
  2. Message level security – WS-Security

See my previous blog comparing Transport level and Message level security.

If you are satisfied with the security provided by using just ‘SOAP over HTTPS’, you can get the work done by configuring your server (Apache or IIS) to enable ssl. See http://www.onlamp.com/pub/a/onlamp/2008/03/04/step-by-step-configuring-ssl-under-apache.html for an step by step guide for configure SSL in your Apache server.

If you want message level security for your application, just use WS-Security. With WSF/PHP it is even easier to implement than SOAP over HTTPS method, because you can provide the certificates programatically in PHP and no need to do further configuration.

WSF/PHP provides you two classes in line with WSService to implement an API to provide WS-Security.

  1. WSPolicy -Let you provide rules that the engine need to follow in securing the message. E.g.
    $policy = new WSPolicy(array("security"=> array("encrypt" => TRUE,
                        "algorithmSuite" => "Basic256Rsa15",
                        "securityTokenReference" => "IssuerSerial")));

    In fact you can load policies from an xml which adheres to the WS-SecurityPolicy specification.

  2. WSSecurityToken – Keeps the security tokens like certificates, keys, username, passwords which would be used when applying the rules specified in the policy. E.g.
    $sec_token = new WSSecurityToken(array("privateKey" => $pvt_key,
                                           "receiverCertificate" => $pub_key));

You can see the WS-Security in action on live from http://labs.wso2.org/wsf/php/samples/security/ and security demo ource codes.


© 2007 Dimuthu’s Blog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress