我们想要创建一个使用WS-Security但没有签名和加密的PHP WSO2 Web服务客户端。相反,我们想要使用一个简单的密码。问题是:我们总是收到一个证书错误(见下文)。我们真的必须安装证书吗?如果必须,在哪里?Java密钥库?
环境:PHP 5.3.10、WSO2 PHP 2.10、Apache 2.2.x
wfs_client_log:
[error]key_mgr.c(295)[rampart][rampart_signature]未指定公钥证书文件。[error]rampart_signature.c(856)[rampart][rampart_ssignature]无法获取证书[error]rampart_sec_header_builder.c(131)[rampart][shb]签名失败。错误[error]rampart_sec_header_builder.c(601)[rampart][shb]不对称绑定失败[error]rampart_out_handler.c(130)[rampart]安全标头构建失败。[error]阶段.c(224)处理程序RampartOutHandler调用在阶段Security内失败[error]engine.c(657)调用阶段安全性失败
PHP代码是:
<?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);
终于成功了!调用Web服务(使用上面提到的vector/intent)现在可以工作了。
Nandika后来的许多尝试和另一个例子发现,对我们(Matthias和我)来说,改变WS-SecurityPolicy-对象的创建起到了作用。
不使用上面的数组作为初始化参数:
// create SecurityPolicy
$policy = new WSPolicy(array(
"security" => array(
"useUsernameToken" => TRUE)));
我们现在使用这样一个xml策略文件:
// load Policy (xml) file...
$policy_file = file_get_contents("policy.xml");
// ...and create SecurityPolicy
$policy = new WSPolicy($policy_file);
"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>
开始将WSO2与WS-Security WSF/PHP 2.1一起使用感觉相当棘手。因此,我将尝试列出一些知道(会)帮助我节省时间的想法:
wsf/php反映给我的最常见错误是(一个带有消息的异常对象):"error,NO-ResponseReceived"。现在,这种情况几乎发生在任何出错的时候,例如:
- 我的请求xml(-structure)无效
- 参数的类型不正确
- Web服务抛出异常(任何异常:可能是因为错误的WS-Security用户/密码、丢失/未知的命名空间,甚至是一些"WS-Fault"类型的异常)
- 服务方面出了什么问题
- php/wsf端的错误配置/配置更改不允许任何相关内容
- 网络问题?(…未确认)
- wso2不发送任何请求(例如,当TransportBinding-confinguration出现问题时)
有时我确实会得到一个WS Fault-ojbect(在resopnse信封中),我可以检查我的客户端代码[$e typeof WSFault]
附近总是有一个具有代理功能的工具来路由+检查您的请求和响应。目前,我使用的是OracleJDeveloper10和11,它们内部都有一个整洁的小"HTTP分析器"(但肯定有更小和/或更好的工具用于此目的)。
玩policy.xml中的设置,我发现:
- 如果有一个而不是所需的节点(在security_policy.xml中),您将得到一个WS-Fault:"policy requires authentication token"
- 有一个空节点会导致浏览器中的连接终止,wsf/php崩溃(据我所见,没有明显的错误消息)
感谢大家(尤其是Nandika)的帮助!
我曾经遇到过同样的问题,但它与WSServer有关,而不是WSClient。由于2.1版(甚至更早版本)WSF考虑默认签名的WS-Policy,因此需要一个声明无签名行为的WSPolicy文件。我已经发表了一篇关于这个话题的文章,但它是用俄语写的。使用谷歌翻译。
http://habrahabr.ru/post/132353/
默认生成的策略失败,因为wsf/php 2.1.0版本要求为$policy=新的WSPolicy(数组("security"=>数组("useUsernameToken"=>TRUE));
请尝试使用以下策略文件。https://svn.wso2.org/repos/wso2/trunk/wsf/php/samples/security/username_token/call_back/policy.xml
您可以将策略加载为$policy_file=file_get_contents("policy.xml");$policy=新的WSPolicy($policy_file);