1
votes

we want to create a PHP WSO2 Webservice Client which uses WS Security, but without signature nor encryption. Instead we want to use a simple Password. Problem is: we always get an certificate error (see below). Do we really have to install a certificate, and if so: where ? Java Keystore ?

Environment: PHP 5.3.10, WSO2 PHP 2.10, Apache 2.2.x

wfs_client_log:

[error] key_mgr.c(295) [rampart][rampart_signature] Public key certificate file is not specified. [error] rampart_signature.c(856) [rampart][rampart_signature] Cannot get certificate [error] rampart_sec_header_builder.c(131) [rampart][shb] Signing failed. ERROR [error] rampart_sec_header_builder.c(601) [rampart][shb] Asymmetric Binding failed [error] rampart_out_handler.c(130) [rampart]Security header building failed. [error] phase.c(224) Handler RampartOutHandler invoke failed within phase Security [error] engine.c(657) Invoking phase Security failed

PHP Code is:

  <?php
    // Endpoint WebService
    $endPoint       = 'http://xxx.xxxx.xxx:7000/orabpel/selfservice/passwortAendernMBE/1.0';

    // Security-Payload
    $user           = 'mustermann123';
    $passwortAlt    = 'foo';
    $passwortNeu    = 'bar';

    // create Security-Token 
    $secToken       = new WSSecurityToken(array(
                                                    "user" => $user,
                                                    "password" => $passwortAlt,
                                                    "passwordType" => "PlainText"));
    // create SecurityPolicy 
    $policy         = new WSPolicy(array(
                                                    "security" => array(
                                                            "useUsernameToken" => TRUE)));
    // create WS-Client 
    $client         = new WSClient( array(
                                                    "to" => $endPoint,
                                                    "useSOAP" => "1.1",
                                                    "action" => "process",
                                                    "policy" => $policy,
                                                    "securityToken" => $secToken));
    // create SOAP-Payload
    $soapPayload = '
            <ns1:passwortAendern_processElement xmlns:ns1="http://xxxx.xxxx.xxxxxe/Integration/prozesse/xxxxxxSchema"
            xmlns:ns2="http://xxxx.xxxx.xxx/types/xx.xxx.xxxx.selfService.prozesse.xxx.xxxxMessage">
                    <ns1:passwortAendernMessage>
                            <ns2:benutzerkennung>' . $user . '</ns2:benutzerkennung>
                            <ns2:passwortAlt>' . $passwortAlt . '</ns2:passwortAlt>
                            <ns2:passwortNeu>' . $passwortNeu . '</ns2:passwortNeu>
                    </ns1:passwortAendernMessage>
            </ns1:passwortAendern_processElement>';

    // Request
    $soapResponse = null;
    try {
            // soap Request 
            $soapResponse   = $client->request( $soapPayload );

            // print out Response
            echo '<pre>';
            print_r(htmlspecialchars( str_replace('>','>'.PHP_EOL,$soapResponse->str ) ));
            echo '</pre>';

    } catch(Exception $e) {
            echo '<h1>Error:</h1>' . PHP_EOL;
            var_dump($e);
    }

// dump Soap-Parameters
echo '<h1>Soap-Parameter</h1>' . PHP_EOL;
var_dump($soapPayload);

// dump Soap-Response
echo '<h1>Soap-Response</h1>' . PHP_EOL;
var_dump($soapResponse);
3

3 Answers

1
votes

Finally successful! Calling the Webservice (with above mentioned vector/intent) now works.

Many attempts and another example by Nandika later we've found out that for us (Matthias and I) changing the creation of the WS-SecurityPolicy -object did the trick.

Instead of using above array as initialisation-parameter:

// create SecurityPolicy 
$policy  = new WSPolicy(array(
                 "security" => array(
                       "useUsernameToken" => TRUE)));

...we now use a xml-policy-file like so:

// load Policy (xml) file...
$policy_file = file_get_contents("policy.xml");

// ...and create SecurityPolicy
$policy = new WSPolicy($policy_file);

Content of "policy.xml":

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:TransportBinding>
                <wsp:Policy>
                </wsp:Policy>
            </sp:TransportBinding>
            <sp:SignedSupportingTokens>
                <wsp:Policy>
                    <sp:UsernameToken
                        sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp:WssUsernameToken10 />
                        </wsp:Policy>
                    </sp:UsernameToken>
                </wsp:Policy>
            </sp:SignedSupportingTokens>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

Beginning to use WSO2 with WS-Security WSF/PHP 2.1 feels rather touchy. Therefore I'll try to list some thoughts that knowing (would have) helped me save time:

  • most common error reflected to me by wsf/php is (an exception-object with the message): "Error , NO Response Received". This now happens almost whenever anything goes wrong, for example:

    • my request-xml (-structure) is not valid
    • a parameter has an incorrect type
    • the webservice throws an Exception (any exception really: be it because of a wrong WS-Security user/password, missing/unknown namespace, even some exceptions of type 'WS-Fault')
    • anything going wrong on the service-side really
    • a misconfiguration / configuration-change on php/wsf -side that disallowes anything relevant
    • network problems? (...not confirmed)
    • no request is sent by wso2 (for example when having trouble with TransportBinding -confinguration)
  • sometimes I do get a WS-Fault -ojbect (in a resopnse envelope) which I can check for my client-code [$e typeof WSFault]

  • always have a tool with proxy-capabilities nearby to route through + inspect your request and response. At the moment I use Oracles JDeveloper 10 and 11 which both have a neat little "HTTP Analyzer" inside (but there sure are smaller and/or better tools out there for this purpose).

  • Playing around with the settings in policy.xml a comrad and I found out that:

    • having a instead of the needed node (in your security_policy.xml) you'll get a WS-Fault: "policy requires authentication token"
    • having an empty node results in connection terminated in browser and wsf/php crashing (without signifficant error message - as far as i can see).

Thanks everyone (especially Nandika) for your help!

0
votes

I've encountered the same issue once, but it was concerning WSServer, not WSClient. Since version 2.1 (or even earlier) WSF consideres WS-Policy signed by default, you need a WSPolicy file which declared signatureless behaviour. I've posted an article on this topic, but it's in Russian. Use Google Translate.

http://habrahabr.ru/post/132353/

0
votes

The default generated policy is failing because, wsf/php 2.1.0 version is expecting signed messages for default generated policy for $policy = new WSPolicy(array( "security" => array("useUsernameToken" => TRUE)));

Try with the following policy file. https://svn.wso2.org/repos/wso2/trunk/wsf/php/samples/security/username_token/call_back/policy.xml

You can load the policy as $policy_file = file_get_contents("policy.xml"); $policy = new WSPolicy($policy_file);