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.

Username token is a simple token sent inside SOAP message header element with username and password information.  It is used to authenticate SOAP messages in a standardized way.

Sending Username Token

To send username token with WSF/PHP you can use the generic API designed to implement WS-Security scenarios.

  • First you need to declare the security policy saying you are using username token. You can do this either with a policy which is complaint with WS-Security Policy standards or using an associative array. Here we use the second approach which is more PHP-Friendly.
    array("useUsernameToken" => TRUE)
  • With a WSSecurityToken instance we are giving our user parameters. In this case it is username, password and the password type.
    $security_token = new WSSecurityToken(array("user" => "my_username",
                                                    "password" => "my_password",
                                                    "passwordType" => "Digest"));
  • And create the WSClient object with policy and the security token object you just created + with “useWSA” on.  This is to enable the addressing headers in the request message which guide the server to identify the service and the operation.

Here is the complete code for the client.

    // Set up security options
    $security_options = array("useUsernameToken" => TRUE );
    $policy = new WSPolicy(array("security" => $security_options));
    $security_token = new WSSecurityToken(array("user" => "my_username",
                                                "password" => "my_password",
                                                "passwordType" => "Digest"));

    // Create client with options
    $client = new WSClient(array("useWSA" => TRUE,
                                 "policy" => $policy,
                                 "securityToken" => $security_token));

    // Send request and capture response
    $resMessage = $client->request($reqMessage);

Handling Username Token at Server Side
The same options (”policy” and “securityToken”) you gave to WSClient, can be given to WSService object as well. But hard coding values for “username” and “password” in SecurityToken is not much useful at the server side. Because it authenticate only one user. So in order to maintain multiple accounts, you have to have a callback function in php.

// callback function
function my_passwd_callback_function($username)
{
    // logic to return the password for the username
    return $password
}

// setting it to the security token
$sec_token = new WSSecurityToken(array("passwordCallback" => "my_passwd_callback_function",
                                       "passwordType" => "Digest"));

Here in the function you return the password for the username from a database and that information will be used to authenticate the request message.