在php中连接到soap

时间:2017-05-31 15:25:39

标签: php soap

我必须使用wssecurity与soap客户端连接,我正在使用MySoapClient类(下面的代码),我做错了什么?

我可以列出肥皂功能:

Array (
  [0] => tcreateQuejaResponse createQueja(tcreateQuejaRequest $input)
  [1] => tgetListaValoresResponse getListaValores(tgetListaValoresRequest $input)
  [2] => getVersionResponse getVersion(getVersion $output)
)

当我尝试启动soap功能时,我收到此错误:

SoapFault exception: [soapenv:Server] integration error in prueba-5.php:79 Stack trace: #0 prueba-5.php(79): SoapClient->__call('getListaValores', Array) #1 prueba-5.php(79): SoapClient->getListaValores() #2 {main}

我尝试了不同的方式,我也得到了这个错误:

Fatal error: Uncaught SoapFault exception: [soapenv:Server] integration error in prueba-3.php:116 Stack trace: #0 prueba-3.php(116): SoapClient->__call('createQueja', Array) #1 prueba-3.php(116): SoapClient->createQueja(Object(stdClass)) #2 {main} thrown in prueba-3.php on line 116

我有一个包含不同字段的数组(姓名,姓氏......)。

$var = new MySoapClient;
$var_client = $var->getClient('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', '**USER**', '**PASSWORD**', 'soap/name.wsdl', null);

类别:

class WSSoapClient extends SoapClient
{
    private $OASIS = 'http://docs.oasis-open.org/wss/2004/01';
    /**
     * WS-Security Username
     * @var string
     */
    private $username;

    /**
     * WS-Security Password
     * @var string
     */
    private $password;

    /**
     * WS-Security PasswordType
     * @var string
     */
    private $passwordType;

    /**
     * Set WS-Security credentials
     *
     * @param string $username
     * @param string $password
     * @param string $passwordType
     */
    public function __setUsernameToken($username, $password, $passwordType)
    {
        $this->username = $username;
        $this->password = $password;
        $this->passwordType = $passwordType;
    }

    /**
     * Overwrites the original method adding the security header.
     * As you can see, if you want to add more headers, the method needs to be modified.
     */
    public function __call($function_name, $arguments)
    {
        $this->__setSoapHeaders($this->generateWSSecurityHeader());
        //var_dump($this);
        return parent::__call($function_name, $arguments);
    }

    /**
     * Generate 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.
     *
     * @return string   base64 encoded password digest
     */
    private function generatePasswordDigest()
    {
        $this->nonce = mt_rand();
        $this->timestamp = gmdate('Y-m-d\TH:i:s\Z');

        $packedNonce = pack('H*', $this->nonce);
        $packedTimestamp = pack('a*', $this->timestamp);
        $packedPassword = pack('a*', $this->password);

        $hash = sha1($packedNonce . $packedTimestamp . $packedPassword);
        $packedHash = pack('H*', $hash);

        return base64_encode($packedHash);
    }

    /**
     * Generates WS-Security headers
     *
     * @return SoapHeader
     */
    private function generateWSSecurityHeader()
    {
        if ($this->passwordType === 'PasswordDigest')
        {
            $password = $this->generatePasswordDigest();
            $nonce = sha1($this->nonce);
        }
        elseif ($this->passwordType === 'PasswordText')
        {
            $password = $this->password;
            $nonce = sha1(mt_rand());
        }
        else
        {
            return '';
        }
        $xml = '
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="' . $this->OASIS . '/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken>
    <wsse:Username>' . $this->username . '</wsse:Username>
    <wsse:Password Type="' . $this->OASIS . '/oasis-200401-wss-username-token-profile-1.0#' . $this->passwordType . '">' . $password . '</wsse:Password>
    <wsse:Nonce EncodingType="' . $this->OASIS . '/oasis-200401-wss-soap-message-security-1.0#Base64Binary">' . $nonce . '</wsse:Nonce>';

        if ($this->passwordType === 'PasswordDigest')
        {
            $xml .= "\n\t" . '<wsu:Created xmlns:wsu="' . $this->OASIS . '/oasis-200401-wss-wssecurity-utility-1.0.xsd">' . $this->timestamp . '</wsu:Created>';
        }

        $xml .= '
    </wsse:UsernameToken>
</wsse:Security>';

        return new SoapHeader(
            $this->OASIS . '/oasis-200401-wss-wssecurity-secext-1.0.xsd',
            'Security',
            new SoapVar($xml, XSD_ANYXML),
            true);
    }
}

1 个答案:

答案 0 :(得分:0)

你应该首先使用WSDL来处理php等错误,例如PackageGenerator项目,以便使用对象轻松构造请求并使用已知对象类处理响应,

其次,您应该尝试使用WsSecurity库轻松添加WsSecurity标头