0

我尝试使用 usernameToken 呼叫合作伙伴 WS。我在 php5.2.x 下使用那个 ws02 wsf_2.0.0 并且它摇摆不定。现在我们要迁移到基于php5.3的不同解决方案上,好在ws02提供了一个2.1.0标签,兼容php5.3。我花时间阅读了这个新版本的新特性和文档,尤其是关于 usernameToken 的内容。我了解此版本通过证书和私钥使用有关 usernameToken 的签名。我猜是 AsymetricTransportBinding 政策的 b/c。就我而言,我不想通过证书或其他方式签署任何东西。我还读到 ws02 在单独的 xml 文件中提供了一种回退以避免任何签名。

在阅读了许多帖子后,论坛我需要社区 b/c 的一些帮助,我完全被困住了。

这是用于在 php5.3 - wsf 2.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:CalculationServiceHttpBinding" wsdlsoap:address location="http://www.xxxx.xx/comparatorservices/CalculationService" /wsdl:port

现在从调试日志中我发现了这个:

[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 Header

这是 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 是假的……但是为什么呢?有没有聪明的人来解释什么是错的?

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

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

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

请帮助!

4

1 回答 1

0

我终于找到了问题并修复了rampart_in_handler.c:91

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

是否符合标准,在最后一个版本 ( 2.0.0 ) 中它正在工作。所以我决定稍微调整一下rampart_in_handler.c文件中的代码,以在soap头丢失的情况下返回成功......

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

对soapHeader 响应的测试肯定是在asymetricBinding 传输和新签名的usernametoken 案例的b/c 中添加的。但是,如果我们想使用 usernametoken 而不签名(通过基本的 policy.xml并且响应是在没有任何 soap:Header 的情况下做出的;那么壁垒总是会返回失败...

此外,我分析了 scripts/ 文件夹下有关 wsf 处理响应方式的 php 代码,我在此文件中看到:wsf_wsdl.php在函数下wsf_process_response()

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.php最后但并非最不重要的一点是,我在和wsf_wsdl_deserialization.php文件上都发现了一个奇怪的错误。

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

                            "110% Sigma of something" 

它会在序列化/反序列化过程中失败并创建一个段错误!

现在我想知道自己为什么?但乍一看,“110% Sig..”肯定包含“%S”,而且它与“%s”非常接近……

我认为这个错误是这里提到的这个:

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

如果我将 S 更改为 D 或其他任何东西,它会起作用......

多么痛苦……

于 2012-07-28T20:49:42.723 回答