这是一个会把人搞疯掉的问题。

论坛上大部分人都会用一个短语来形容这个破问题,就是drive me nut!!!

想用php来调用一个设置了身份安全认证的.net写的webservice,我试过了各种方法,就差自己重写php了啊,有没有啊。

最开始是用nusoap,结果发现nusoap根本不支持soap1.2 有木有,

只能用soap1.1,这是什么时代了啊,居然还不支持soap1.2,这是以后不打算让别人用了啊,有没有啊。

(虽然最后还是让服务器端把webservice改成了1.1版的,但是nusoap依然不给力的通不过安全认证。我还没有研究出来原因,有待高手进一步解决。)

然后又用php自带的soapclient类来实现,结果发现我们购买的虚拟空间根本不支持soapclient,调用时返回的居然是没有该类。。

打开phpinfo();查看,又写着soapclient已经安装启用了!!!

这类到底是有木有,有木有,有木有啊!!!

于是又换方法。

又尝试curl,curl参数多少知道吗,用户名密码都输进去了,参数一个一个试都不管用,最后我甚至完全自己写一个header发过去等server给response,他居然还是说没有安全认证,有没有啊!

最后终于在一个论坛上找到了解决方法。!!!(你以为这很容易吗?之前至少找到几十个帖子我当时都认为是找到解决方法了,一个一个测试都不行,直到这个才成功,当soap返回数据的时候我差点就激动的哭出来了,有没有,有没有,有木有!!!)

不咆哮了,贴出帖子地址:

 
简单翻译一下,
帖子:
“这是webservice 的vb代码
Dim client As SupplierServiceClient New SupplierServiceClient() 
client.
ClientCredentials.UserName.UserName “xxxx@xxx.xx.xx” 
client.
ClientCredentials.UserName.Password “password” 

Dim SupplierList As List(Of Supplier) = client.GetSuppliers()
 
想用php调用。
回答:
 

“我想用php建立soap的认证,但是试了好多次都不行。刚开始我试着用这个:

$header = new stdClass; 
$credentials = new stdClass; 
$credentials->Username="myuser"
$credentials->Password="mypass"
$header->UsernameToken = $credentials; 

$securityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
$client->__setSoapHeaders($securityNamespace, 'Security', $header); 

这个不行,好像php3(我的是v5.3.5)有个bug,它不给包含在header里面的tag加上命名空间的前缀

http://bugs.php.net/bug.php?id=48966
最后我用这个:

<UsernameToken><Username>myuser</Username><Password>myuser</Password></UsernameToken> 

代替了这个:

<o:UsernameToken><o:Username>myuser</o:Username><o:Password>myuser</o:Password></o:UsernameToken> 
所以,我就把代码写死了,把需要的xml直接赋值给变量,代码很不好看,但是管用。
$securityNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
$headerContent = "<o:Security xmlns:o=\"$securityNamespace\"> 
                    <o:UsernameToken> 
                    <o:Username>myuser</o:Username> 
                    <o:Password>mypass</o:Password> 
                    </o:UsernameToken> 
                </o:Security>"
$headerVar = new SoapVar($headerContent, XSD_ANYXML, nullnullnull); 
$header = new SoapHeader($securityNamespace, 'o:Security', $headerVar); 
$client->__setSoapHeaders(array($header)); 

希望这些代码有用。

感谢这位大仙啊,这些代码居然真的管用了。我也把它发上来,希望有人用中文搜索这个问题时,也能找到想要的答案。

最后说一句,用php调用有身份认证的.net的webservice的程序员,你们伤不起啊,啊啊啊!!!