如何在php5中实现ws-security 1.1

如何在php5中实现ws-security 1.1,php,web-services,zend-framework,soap,ws-security,Php,Web Services,Zend Framework,Soap,Ws Security,我试图在PHP5中使用Soap调用Web服务,为此,我需要使用WS-Security 1.1 (在java和.NET中,这都是自动生成的。) 是否有任何框架可以在PHP中轻松生成安全头?还是我必须自己添加整个标题 WS-Security 1.1的规范:在上,Roger Veciana i Rovira提交了以下内容(我刚刚重新格式化了代码): 类WSSoapClient扩展了SoapClient{ 私有$username; 私人$password; /*生成安全标头*/ 私有函数wssecuri

我试图在PHP5中使用Soap调用Web服务,为此,我需要使用WS-Security 1.1

(在java和.NET中,这都是自动生成的。)

是否有任何框架可以在PHP中轻松生成安全头?还是我必须自己添加整个标题

WS-Security 1.1的规范:

在上,Roger Veciana i Rovira提交了以下内容(我刚刚重新格式化了代码):

类WSSoapClient扩展了SoapClient{
私有$username;
私人$password;
/*生成安全标头*/
私有函数wssecurity_header(){
/*时间戳。计算机必须准时或您所在的服务器
*为了安全起见,连接可能会拒绝密码摘要。
*/
$timestamp=gmdate('Y-m-d\TH:i:s\Z');
/*一个随机词。如果服务器不可用,则使用rand()可能会重复该词
*负载很重。
*/
$nonce=mt_rand();
/*这是创建密码摘要的正确方法
*直接使用密码也可以,但传输它并不安全
*没有加密。无论如何,至少在axis+wss4j中,nonce
*无论如何,时间戳都是必需的。
*/
$passdigest=base64\u编码(
包装('H*',
沙一(
pack('H*',$nonce).pack('a*',$timestamp)。
打包('a*',$this->password));
$auth='1
“.$this->username。”
“.$passdigest。”
“.base64_编码(pack('H*',$nonce))。”
“.$timestamp。”
';
/*XSD_ANYXML(或147)是将xml直接添加到SoapVar中的代码。
*使用其他代码,如SOAP_ENC,设置
*请更正变量的命名空间,以便axis服务器拒绝
*xml。
*/
$authvalues=newsoapvar($auth,XSD_ANYXML);
$header=新的SoapHeader(“http://docs.oasis-open.org/wss/2004/01/oasis-".
“200401-wss-wssecurity-secext-1.0.xsd”、“安全性”、$authvalues、,
正确的);
返回$header;
}
/*如果要设置不同的用户,则必须调用它
*密码
*/
公共函数\uuuu setUsernameToken($username,$password){
$this->username=$username;
$this->password=$password;
}
/*覆盖添加安全标头的原始方法
*请参见,如果要添加更多标题,则需要修改该方法
*/
公共函数\uuuSOAPCALL($function\u name,$arguments,$options=null,
$input\u headers=null,$output\u headers=null){
$result=parent::uu soapCall($function\u name,$arguments,$options,
$this->wssecurity_header());
返回$result;
}
}

我注意到这是针对1.0版的,但希望它能让您走上正轨。感谢您的回复,现在我得到了下一个异常Uncaught SoapFault异常:[HTTP]无法处理邮件,因为内容类型为“text/xml;charset=utf-8“不是预期的类型”application/soap+xml;字符集=utf-8'。在/home/projects/caheritage/site/providence/app/lib/core/WSSoapClient.php:80中,您知道如何解决这个问题吗?wsHttpBinding(SOAP 1.2)使用“application/SOAP+xml”内容类型,basicHttpBinding(SOAP 1.1)使用“text/xml”,因此请确保您的php和WCF匹配。ie-在WCF中调用basic或ws绑定时,确保PHP设置为使用正确的SOAP版本
class WSSoapClient extends SoapClient {

    private $username;
    private $password;
    /*Generates de WSSecurity header*/
    private function wssecurity_header() {

        /* The timestamp. The computer must be on time or the server you are
         * connecting may reject the password digest for security.
         */
        $timestamp = gmdate('Y-m-d\TH:i:s\Z');
        /* A random word. The use of rand() may repeat the word if the server is
         * very loaded.
         */
        $nonce = mt_rand();
        /* This is the right way to create the password digest. Using the
         * password directly may work also, but it's not secure to transmit it
         * without encryption. And anyway, at least with axis+wss4j, the nonce
         * and timestamp are mandatory anyway.
         */
        $passdigest = base64_encode(
                pack('H*',
                        sha1(
                                pack('H*', $nonce) . pack('a*',$timestamp).
                                pack('a*',$this->password))));

        $auth = '
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.'.
'org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
    <wsse:Username>'.$this->username.'</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-'.
'wss-username-token-profile-1.0#PasswordDigest">'.$passdigest.'</wsse:Password>
    <wsse:Nonce>'.base64_encode(pack('H*', $nonce)).'</wsse:Nonce>
    <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-'.
'200401-wss-wssecurity-utility-1.0.xsd">'.$timestamp.'</wsu:Created>
   </wsse:UsernameToken>
</wsse:Security>
';

        /* XSD_ANYXML (or 147) is the code to add xml directly into a SoapVar.
         * Using other codes such as SOAP_ENC, it's really difficult to set the
         * correct namespace for the variables, so the axis server rejects the
         * xml.
         */
        $authvalues = new SoapVar($auth,XSD_ANYXML);
        $header = new SoapHeader("http://docs.oasis-open.org/wss/2004/01/oasis-".
            "200401-wss-wssecurity-secext-1.0.xsd", "Security", $authvalues,
                true);

        return $header;
    }

    /* It's necessary to call it if you want to set a different user and
     * password
     */
    public function __setUsernameToken($username, $password) {
        $this->username = $username;
        $this->password = $password;
    }


    /* Overwrites the original method adding the security header. As you can
     * see, if you want to add more headers, the method needs to be modifyed
     */
    public function __soapCall($function_name, $arguments, $options=null,
            $input_headers=null, $output_headers=null) {

        $result = parent::__soapCall($function_name, $arguments, $options,
                $this->wssecurity_header());

        return $result;
    }
}