WS02 / WSF PHP 2.1.0 UsernameToken issues



我尝试使用usernameToken调用合作伙伴WS。我使用php5.2.x下的ws02 wsf_2.0.0,它很震撼。现在,我们希望在基于php5.3的不同解决方案上进行迁移,幸运的是,ws02提供了与php5.3兼容的2.1.0标记。我花时间阅读了这个新版本的新功能和文档,尤其是关于usernameToken的。我理解这个版本通过证书和私钥对usernameToken进行签名。我猜是AsymetricTransportBinding策略的b/c。就我而言,我不想通过证书或其他方式签署任何东西。我还读到ws02在一个单独的xml文件中提供了一种回退,以避免任何签名。

在阅读了许多帖子、论坛后,我需要社区的一些帮助,我完全陷入了困境。

以下是用于在php5.3-wsf2.1.0中请求WS的代码(使用HTTP)

$policy   = new WSPolicy( $policy ); ( $policy is the one from the call_back folder with a file_get_contents() )
$security = new WSSecurityToken( array(
  'user'                    => 'my_username',
  'password'                => 'my_password',
  'passwordType'            => 'Digest',
  'ttl'                     => '300'
));
$this->oSoapClient = new WSClient( array(
  wsdl:          http://www.xxx.xx/comparatorservices/CalculationService?WSDL
  to:            http://www.xxx.xx/comparatorservices/CalculationService
  useWSA:        true
  useSOAP:       1.1,
  policy:        $policy,
  securityToken: $security
));
$proxy = $this->oSoapClient->getProxy();
$response = $proxy->wykonajKalkulacje( $MySuperRequestObject );

在此步骤:

  1. 我激活了调试跟踪(日志级别4)
  2. 我确认我的"to"是根据wsdl定义使用http

    wsdl:port name="CalculationServiceHttpPort"binding="tns:CalculationServiceHTTP绑定"wsdlsoap:address location="http://www.xxxx.xx/comparatorservices/CalculationService"/wsdl:端口

现在,从调试日志中,我发现:

[Wed Jul 25 05:22:53 2012] [error] rampart_in_handler.c(91) [rampart]SOAP header cannot be found.
[Wed Jul 25 05:22:53 2012] [error] phase.c(224) Handler RampartInHandler invoke failed within phase Security
[Wed Jul 25 05:22:53 2012] [error] engine.c(657) Invoking phase Security failed
[Wed Jul 25 05:22:53 2012] [error] engine.c(262) Invoking operation specific phases failed for operation __OPERATION_OUT_IN__
[Wed Jul 25 05:22:53 2012] [error] /home/agruet/08_KRK_sources/wso2-wsf-php-src-2.1.0/src/wsf_wsdl.c(1226)      [wsf_wsdl] Response envelope not found

因此,我的第一个想法是探查流量,尤其是工作(wsf_2.0.0/php5.2.x)和中断(wsf~2.1.0/php5.3)之间的SOAP标头

这是2.0.0版本(正在运行)的

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>my_username</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
              hashed(my_password)
            </wsse:Password>
            <wsse:Nonce>hashed</wsse:Nonce>
            <wsu:Created>2012-07-26T20:40:26.991Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

和2.1.0(不工作/损坏)

         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Header>
         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>my_username</wsse:Username>
            <wsse:Password
                Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">hashed(my_password)</wsse:Password>
            <wsse:Nonce>hashed</wsse:Nonce>
            <wsu:Created>2012-07-25T00:44:56.758Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

正如您所看到的,唯一的区别来自wsse:Security命名空间。(缺少xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/)

仅此而已。。。

根据调试日志检查第91行的rampart_in_handler.c说:

soap_header = axiom_soap_envelope_get_header(soap_envelope, env);
    if(!soap_header)
    {
        /*No SOAP header, so no point of proceeding. FAIL*/
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]SOAP header cannot be found.");
        return AXIS2_FAILURE;
    }

意思是。。。。soap_header为false。。但为什么呢?有没有聪明的人可以解释出了什么问题?

注1:我检查了从工作(2.0.0)发送给合作伙伴WS的策略,它似乎使用了AsymetricBinding。。。维奇很奇怪,因为在2.0.0版本中,我们没有提供任何证书或密钥。

注2:我还尝试将签名的用户名令牌与经典的WSPolicy对象数组参数一起使用-我创建了一个x509证书和私钥,然后使用函数加载这些文件,并使用数组参数将其加载到WSSecurity构造函数中。。。但我收到了同样的错误/Sniffing是一种痛苦b/c数据被加密或类似的东西(以这种方式似乎很正常)

注3:目前在Ubuntu10.04-3LTS上使用apt-get-预编译的php包进行了测试

救命!

我终于发现了问题,并修复了rampart_in_handler.c:91

问题来自回应,而不是请求。。。我通过tcp嗅探器进行了检查,来自合作伙伴WS的响应没有任何soap:Header。

无论是否符合标准,在上一个版本(2.0.0)中,它都在工作。因此,我决定稍微调整rampart_in_handler.c文件中的代码,以便在缺少soap头的情况下返回成功。。。

在我看来,如果我错了,PLZ会纠正我:

soapHeader响应的测试当然是添加到asymmetricBinding传输和新签名的usernametoken情况的b/c中的。但是,如果我们想在不签名的情况下使用usernametoken(通过基本策略.xmlAND,则在不使用任何soap:Header的情况下进行响应;那么rampart总是会返回一个失败。。。

此外,我还分析了脚本/文件夹下关于wsf处理响应的方式的php代码,并在这个文件上看到了函数wsf_process_response():下的wsf_wsdl.php

if($response_header_string && !empty($response_header_string)) {
    $header_dom = new DomDocument();
    $header_dom->preserveWhiteSpace = FALSE;
    $header_dom->loadXML($response_header_string);
}

这意味着在php方面,当接收到数据时,wsf/php假设一个没有任何soapHeader的情况。。。(如果缺少soapHeader,就不会失败)超级奇怪!?

最后,我在wsf_wsdl_serialization.phpwsf_wsdl_deserialization.php文件上都发现了一个奇怪的错误。

例如,如果您计划用这样的字符串发送和/或接收参数/值:

                            "110% Sigma of something" 

它将失败,并在序列化/取消序列化过程中创建segfault!

现在我在想为什么?但从第一个角度来看,"110%Sig.."包含"%S",而且它相当接近"%S"。。。

我认为这个bug就是这里提到的这个:

http://old.nabble.com/WSF-PHP-server-segfault-on-wsf_wsdl_serialization.php---td24329956.html

如果我把S改成D或其他什么,它就行了。。。

多么痛苦。。。

相关内容

  • 没有找到相关文章

最新更新