Showing posts with label Web Services. Show all posts
Showing posts with label Web Services. Show all posts

Thursday, September 18, 2008

Debugging PHP Web Services

One of the difficulties of doing distributed computing, is the difficulty of debugging when things are not going well. It is no exception for Web Services. Since messages are exchanged between services, clients, we have to have some mechanisms  to capture messages, view the soap messages exchanged, some known error messages etc.

Capturing Messages

One of the most well known technique in debugging web services calls is to  some tcp message capture tool to capture the messages exchanged. There are few such good tools for this task.

1. TCPMON tool from apache

             This is a very simple and easy to use tool which has very wide adoption and is quite popular among developers. You can download this tool from apache tcpmon site. 

2. SOAP UI

            This is another popular tool for debugging and developing SOAP based applications. This tool is able to generate request SOAP message for a given WSDL where you fill out the values and send a valid soap request and response. This is a very useful tool to get started with Web Services. You can download soap UI from soapui.org

3.   Ethereal

         This is another tool that is quite useful is capturing and analyzing messages. http://thud.ethereal.com/

Using debugging functions from framework

you can you framework provided functions for debugging. For example WSF/PHP provides two functions getLastRequest() and getLastResponse() on the WSClient class which returns the exchanged request and response messages. Also it provides functions to obtains the returned HTTP headers. Using these, you can also do some debugging.

Logging

Logging is another useful techniques to idenfity possible problems. You can look as the wsf_php_client.log and wsf_php_server.log files and get an idea of what went wrong. If you are not able to trace what's wrong using the logs , you can post your problem with the appropriate log messages to the forum  and get support.

Using Known Error Messages

Another useful technique is to go through the known set of error messages to locate what went wrong. In WSF/PHP, here are some of the error messages you can get.

Thursday, July 31, 2008

New features to be released with WSF/PHP

Since the 1.3.2 release of WSF/PHP, a lot of new functionality has been added to the extension. In addition to that many bugs have been corrected. Following are some of the new features that will be released with the next release.

Improved MTOM/SwA attachment support

One of the limitations of WSF/PHP attachment support was that the service was not handling the http chunked messages. Also there was a limitation on the size of the attachment that can be received by the service.

We have recently fixed this issue. Now both the client and service is able to send binary attachments as chunked. Also with this addition, a service can receive an attachment of any size.

Another limitation we had was that, it was necessary to read the binary file to memory and then set it with the attachments array in order to send an attachment. Now if the file if a large file, this would require a large amount of memory. Now you can set provide the filename and enable caching in order to send the attachment in a memory efficient way.

PKCS12 Key Store support.

This was one of the essential features for implementing WS-Security. Since a access restricted service would want to provide its functionality to a limited number of previously specified clients, it should have the ability to keep track of the clients public certificates in addition to its private in in a single file. This functionality has been added to WSF/PHP.

Improved REST Support

It is quite handy to have the ability to expose you service operations as a REST operation in addition to having it as a soap operation. Now WSF/PHP allows you to map you operations to URL and a HTTP Method so that you can expose the operation as a REST Style operation as well.

PHP Data Services Solution

This is one of the most interesting solutions we have implemented using WSF/PHP. This provides a easy to use framework for exposing the data in you database tables as Web Services. This is compatible with WSO2 WSAS Data Service solution as well. This comes with the WSDL Generation, A database abstraction layer which allows you to use multiple databases and many more features.

WS-Secure Conversation support.

WSF/PHP is now able to support WS-Secure conversation. WSF/PHP allows you can configure a single service to act as a security token service (STS) in addition to providing the secured operations.

Operation Level Policy support

Now you can configure WS Security polices at Operation level with WSF/PHP.

MTOM Attachment Support for Contract First Web Services

This was one of the things that users have been asking for a while. Because of the simplicity of use, Contract first method is preferred by most users. Now WSF/PHP has the support to send and receive attachments in this mode of operation as well.

Sunday, July 13, 2008

How to implement replay detection with WSF/PHP

There are many ways in which a secure messaging system can be attacked. Replay is one such technique. Consider the following scenario. A malicious user who is capturing the encrypted messages exchanged between the client and a service might not be able to know what the exchanged message contains. But he may still be able to do some damage by replaying the messages, if the service is not able to detect whether a received message happen to be a previously received message or not. 

Now a web service secured using WSF/PHP has that capability with its API. Ideally scenario for a secure web service is that, first it should detect replay attack and send appropriate fault message.

Implementing this with WSF/PHP only requires you to implement a function with the specified function signature and pass the name of the function as an argument to the associative array of WSSecurityToken arguments array as "replayDetectionCallback"=>"<function name">.

Lets look at a simple example on how this happens. Each message exchanged between the secured web service , and a client has a unique message id. Sometimes it can contain a timestamp as well. So the replay detection function signature is defined as  bool function_name(string message_id, string time_created [,mixed args]). Here the args is an optional value which is needed in case you want to pass your own set of arguments to the reply detection function.

Now what the replay detection function should do maintain a list of message id+time create values, and check against this list where the newly received values are already in the records. If should the function should return false. If the newly received values are not in the list already there, then add them and return true. Now if the function returned false, WSF/PHP will send a SOAP Fault containing appropriate fault data to the client.Otherwise the request will be handled properly.

The list of records should be persistent. One of the easiest ways to do it is to write to a database. Otherwise you can use a file to maintain this data. In addition to that, you can implement additional features like how long the records should be kept ect.

Now lets look at a simple code example of a replay detection function.

 function array_contains($array_of_string, $str) {
    foreach ($array_of_string as $value) {
        if(strcmp($value, $str) == 0) {
            return TRUE;           
        }
    }
    return FALSE;
}

function replay_detect_callback($msg_id, $time_created) {
    $max_duration = 5;
    if (stristr(PHP_OS, 'WIN')) {
        $replay_file = "replay.content";
    }else{
        $replay_file = "/tmp/replay.content";
    }
    $list_of_records = array();   
    clearstatcache();   
    if(file_exists($replay_file))
    {
        $length = filesize($replay_file);
        $fp_rf = fopen($replay_file, "r");
        if(flock($fp_rf, LOCK_SH)) {
            $content = fread($fp_rf, $length);
            flock($fp_rf, LOCK_UN);
            $tok_rec = strtok($content, '@');
            while($tok_rec) {
                $list_of_records[] = $tok_rec;
                $tok_rec = strtok('@');
            }
        } else {
            echo "Couldn't lock the ".$replay_file." for reading!";
        }
        fclose($fp_rf);
    }else {
        $fp_rf_w = fopen($replay_file, "w");
        if(flock($fp_rf_w, LOCK_EX)) {
            fwrite($fp_rf_w, $msg_id.$time_created.'@');
            flock($fp_rf_w, LOCK_UN);
        } else {
            echo "Couldn't lock the ".$replay_file." for writing!";
        }
        fclose($fp_rf_w);
        return TRUE;
    }

    if(array_contains($list_of_records, $msg_id.$time_created)) {
        return FALSE;
    } else {
        $elements = count($list_of_records);
        if($elements == $max_duration) {
            $new_rcd_list = array_splice($list_of_records, 1);
            $new_rcd_list[] = $msg_id.$time_created;
            $fp_rf_w = fopen($replay_file, "w");
            if(flock($fp_rf_w, LOCK_EX)) {
                foreach($new_rcd_list as $value) {
                    fwrite($fp_rf_w, $value.'@');
                }
                flock($fp_rf_w, LOCK_UN);
            } else {
                echo "Couldn't lock the file for writing!";
            }
            fclose($fp_rf_w);
        } else {
            $list_of_records[] = $msg_id.$time_created;
            $fp_rf_w = fopen($replay_file, "w");
            if(flock($fp_rf_w, LOCK_EX)) {
                foreach($list_of_records as $value) {
                    fwrite($fp_rf_w, $value.'@');
                }
                flock($fp_rf_w, LOCK_UN);
            } else {
                echo "Couldn't lock the file for writing!";
            }

            fclose($fp_rf_w);
        }
    }

    return TRUE;
}

This function is quite simple. it writes each record received to a file named replay.content while implementing the above described logic.  Now lets look at how to use this WSSecurityToken to set this function.


$security_token = new WSSecurityToken(

array("user" => "Raigama", 

"password" => "RaigamaPW",

"passwordType" => "Digest",

"replayDetectionCallback" => "replay_detect_callback", 
"enableReplayDetect" => TRUE));

Note how the callback function is specified. In addition to specifying the callback function, you need to enable Replay detection functionality by setting the option "enableReplayDetect"=>TRUE.

Thursday, May 29, 2008

Tutorial on handling attachments with Axis2/C

I wrote a small know how tutorial on handling MTOM and SwA attachments with Axis2/C

Tuesday, April 1, 2008

PHP Web Services with IIS

I wrote an small guide to installing WSF/PHP in IIS.

Friday, March 21, 2008

Getting the server port in Generated WSDL

WSF/PHP generates WSDL for the familiar ?wsdl. Due to a bug, when the server  is run on a port other than 80, the generated wsdl's location attribute of the address was not printing the port. It is now fixed in the current svn head and you can get the latest nightly build.

Sunday, March 16, 2008

WSO2 WSF/PHP 1.2.1 Released

WSF/PHP Team is pleased to announce the release of WSF/PHP 1.2.1 release. We focused on improving contract first web services support for this release.Schema types support has been improved in this release. All of the current web services stacks for PHP requires the users to go through the WSDL file and pick up the data types and construct his clients and services accordingly. This is quite a cumbersome task. To make this task easier for the user, WSF/PHP 1.2.1 release includes wsdl2php script which can generate the clients and services for a given WSDL. This is an experimental feature that is still it the testing stage. But we hope that is will make the task of implementing Clients and Services easier than ever before.

Another major problem that was fixed in this release was the large attachment support problem. This was an issue that had propagated in to WSF/PHP from WSF/C. Since the changes in WSF/C attachment handling code, the attachments sending and receiving has been made much more efficient. In addition we were able to fix some documentation errors.  Following is the complete feature list for this release.

1. Client API to consume Web services
      * WSMessage class to handle message level options
      * WSClient class with both one way and two way service invocation support
      * Option of using functions in place of object oriented API with ws_request

2. Service API to provide Web services
      * WSMessage class to handle message level options
      * WSService class with support for both one way and two way operations
      * Option of using functions in place of object oriented API with ws_reply

3. Attachments with MTOM
      * Binary optimized
      * Non-optimized (Base64 binary)

4. WS-Addressing
      * Version 1.0
      * Submission

5. WS-Security
      * UsernameToken and Timestamp
      * Encryption
      * Signing
      * WS-SecurityPolicy based configuration

6. WS-Reliable Messaging
      * Single channel two way reliable messaging

7. WSDL Generation for Server Side
      * WSDL generation based on annotations and function signatures, and
        serving on ?wsdl or ?wsdl2 requests

8. WSDL mode support for both client and server side
      * Write services and client based on a given WSDL
      * WS-Addressing and WS-SecurityPolicy is supported in WSDL mode
9. REST Support
      * Expose a single service script both as SOAP and REST service

10. Provide easy to use classes for common services
      * Consume some well known services such as Yahoo search and Flickr
        and Amazon services using predefined classes

Experimental Features
---------------------

11. wsdl2php.php script. This script can generate PHP classes for services
    and clients for a given WSDL to be used with WSDL Mode .

We welcome you you try out this latest release. You can download it from here.

Friday, January 11, 2008

Throwing a custom soap fault from a Web Service

Today I thought of describing how to return a soap fault from a WSF/PHP service.
SOAPFault is used to carry error or status information with in a soap message. For this purpose WSF/PHP extension provideds the pre defined class WSFault with the following constuctor.

WSFault(string code, string reason, string role, string detail).

Lets implement a service with will return the fault code "Sender" with reason value "Fault Test".

WSFault constructor only needs code and reason arguements to be mandatory. The other arguments are optional.

WSFault class extends the exception class. So once you create the WSFault object ,it can be thrown from the function.

Here is the complete source code for a service returning the SOAP Fault.


function sendFault($inMessage) {
throw new WSFault("Sender", "Testing WSFault");
}

$operations = array("getFault" => "sendFault");

$service = new WSService(array("operations" => $operations));

$service->reply();

?>

Wednesday, January 9, 2008

Deploying PHP Web Services using XAMPP for windows

XAMPP is one of the most popular Apache destribution containing Apache, MySql , PHP and PERL. Now it is possible to deploy web services on XAMPP using WSF/PHP extension.

All you need to do is to download WSF/PHP 1.2.0 Win32 Binary release and do the following configuration steps.

1. Unzip the binary package. You will get the directory C:\wso2-wsf-php-bin-1.2.0-win32.
Add C:\wso2-wsf-php-bin-1.2.0-win32\lib directory to PATH environment variable.
( assuming that you unpacked the binary zip to C drive )

2. Copy wsf.dll located in wso2-wsf-php-bin-1.2.0-win32 directory to "C:\xampp\php\ext".
(assuming that you have xampp installed on C drive).

3. Edit the php.ini file located in C:\xampp\apache\bin directory and add following php.ini entries.

extension=wsf.dll

wsf.home=C:\wso2-wsf-php-bin-1.2.0-win32\wsf_c
wsf.log_path=C:\wso2-wsf-php-bin-1.2.0-win32\wsf_c\logs
wsf.log_level=3
wsf.rm_db_dir=C:\wso2-wsf-php-bin-1.2.0-win32\wsf_c

Append C:\wso2-wsf-php-bin-1.2.0-win32\scripts to include_path in php.ini as follows.

include_path = ".;\xampp\php\pear\;C:\wso2-wsf-php-bin-1.2.0-win32\scripts\"

Thats it. Now you are ready to try out the samples. So copy the samples directory (C:\wso2-wsf-php-bin-1.2.0-win32\samples) to C:\xampp\htdocs directory.

Now you should be able to run the samples.

Now you can write your own web services and clients using WSF/PHP.