WS-SecurityPolicy specification defines standards for defining security policies for your web service. WSF/PHP allows you to declare your security policies according to these standards.
You can take one of following approaches to associate policies to your web service or client.
- PHP Array to represent your policies
- Policy file compliant with WS-Security Policy.
- Declaring policies inline with the WSDL.
Declaring Policies with a PHP Array
This is a WSF/PHP specific API to declare policies for a web service. You don’t need to learn WS-Security Policy to write policies with this approach. You can set whether you want to use encryption, signing or usernameToken in a PHP array and create a WSPolicy object using it.
// here is the security array to declare your policies in simple manner $sec_array = array("encrypt" => TRUE, "algorithmSuite" => "Basic256Rsa15", "securityTokenReference" => "IssuerSerial"); // creating WSPolicy instance using the policy array $policy = new WSPolicy(array("security"=> $sec_array));
You can use this policy object to create a service along with a WSSecurityToken which contain the user parameters like the server private key and the client certificate.
$sec_token = new WSSecurityToken(array( "privateKey" => $server_pvt_key, "receiverCertificate" => $client_pub_key)); $svr = new WSService(array("actions" => $actions, "operations" => $operations, "policy" => $policy, "securityToken" => $sec_token)); // here is the policy object you just created $svr->reply();
You can invoke this service just by writing a simple web service client. There also you need to provide the policies declared in the service, so the client can build his request to validate with server policies. You will be using a similar WSPolicy object to set these policies at the client side too, as show in the below code segment.
$sec_token = new WSSecurityToken(array( "privateKey" => $pvt_key, "receiverCertificate" => $rec_cert)); $client = new WSClient(array("useWSA" => TRUE, "policy" => $policy, /* the policy object */ "securityToken" => $sec_token)); $resMessage = $client->request($reqMessage);
Declaring Policies with a Policy File
You can set your policies in the server or client side using a policy file compliant with WS-Security Policy specification. You have to take this approach if your policy requirements are too complicated, like you want to sign only some parts of the message or you want to encrypt some soap headers.
Similar to the above method, here too you will use the WSPolicy object to set your policies. But unlike the above where you give the policies as a PHP array , here you can just give the policy file as an argument to the WSPolicy constructor.
// creating the WSPolicy instance from a policy file $policy_xml = file_get_contents("policy.xml"); $policy = new WSPolicy($policy_xml);
Here is an example of a complete policy file written according to the WS-Security Policy standards. And you can find a quick guide on WS-Security Policy from the article Understanding WS-Security Policy Language written by Nandana, a key leader of Apache Rampart project.
Declaring Policies inline in a WSDL
We use WSDL to describe our web services. WSDL has the information about the service endpoint, the transport protocols (e.g. http), messaging protocols (e.g. SOAP) and the message schemas and many others about the service. You can attach your policies inside a WSDL.
Here is an example of a WSDL with inline policies. The difference in this approach is you can set your policies separately for each messages or each operations or each endpoints of your service. The following segment of a WSDL shows how you refer to different policies which are declared in the early part of the WSDL.
<wsdl:binding name="CalendarSOAP12Binding" type="ns1:CalendarPortType"> <!-- Endpoint policies are declared here. these are common to all messages transferring through this protocols (i.e. SOAP12, http)--> <wsp:PolicyReference URI="#transport_binding_policy"/> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="login"> <soap12:operation soapAction="urn:login" style="document"/> <wsdl:input> <!-- policy specific to the 'login' operation --> <wsp:PolicyReference URI="#username_token_policy"/> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="register"> <!-- no specific policies are set for the 'register' operation <soap12:operation soapAction="urn:register" style="document"/> <wsdl:input> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> .... </wsdl:binding>
This is the binding section of a WSDL where we bind messaging protocol and transport protocols with a service endpoint. Here we have “login” and “register” operations. Note that we are referring to “transport_binding_policy” from the parent level of each operation elements. That means these policies are common to all the operation in that binding. And inside the “login” operation we are referring to “username_token_policy”, so in order to invoke this operation, you have to send username token headers. And “register” doesn’t require any operation specific policies allowing users to register without any prior authentications.
You can select any of the above mentioned approach to define policies of your web service or to invoke a web service that support WS-Policy. If your policy requirements are simple, it will be easy to use the array based approach. If your policy requirements are complex or you have a good understanding of WS-Policy and WS-Security Policy you can rely on the policy file based approach or defining policy inline with WSDL. And the former 2 methods will give you a nice separation of the logic code and security configurations. The selection is yours:)