我尝试使用 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 );
在这一步:
- 我激活了调试跟踪(日志级别 4)
我确认我的“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 包进行测试
请帮助!