简体   繁体   English

使用PHP连接到受WS-Security保护的Web服务

[英]Connecting to WS-Security protected Web Service with PHP

I am trying to connect to a Web Service which is password protected and the url is https. 我正在尝试连接到受密码保护且网址为https的Web服务。 I can't figure out how to authenticate before the script makes a request. 在脚本发出请求之前,我无法弄清楚如何进行身份验证。 It seems like it makes a request as soon as I define the service. 它似乎在我定义服务时立即发出请求。 For instance, if I put in: 例如,如果我投入:

$client = new SoapClient("https://example.com/WSDL/nameofservice",
       array('trace' => 1,)
);

and then go to the site on the browser, I get: 然后在浏览器上访问该站点,我得到:

Fatal error: Uncaught SoapFault exception: 
[WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from
'https://example.com/WSDL/nameofservice' in /path/to/my/script/myscript.php:2 
Stack trace: #0 /path/to/my/script/myscript.php(2): 
SoapClient->SoapClient('https://example...', Array) #1 {main} thrown in 
/path/to/my/script/myscript.php on line 2

If I try defining the service as a Soap Server, like: 如果我尝试将服务定义为Soap服务器,例如:

$server= new SoapServer("https://example.com/WSDL/nameofservice");

I get: 我明白了:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>WSDL</faultcode>
<faultstring>
SOAP-ERROR: Parsing WSDL: 
Couldn't load from 'https://example.com/WSDL/nameofservice'
</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I haven't tried sending a raw request envelope yet to see what the server returns, but that may be a workaround. 我还没有尝试发送原始请求信封,看看服务器返回什么,但这可能是一种解决方法。 But I was hoping someone could tell me how I can set it up using the php built-in classes. 但是我希望有人可以告诉我如何使用php内置类来设置它。 I tried adding "userName" and "password" to the array, but that was no good. 我尝试将“userName”和“password”添加到数组中,但这并不好。 The problem is that I can't even tell if I'm reaching the remote site at all, let alone whether it is refusing the request. 问题是我甚至无法判断我是否到达了远程站点,更不用说它是否拒绝了请求。

Simply extend the SoapHeader to create a Wsse compilant authentication: 只需扩展SoapHeader即可创建Wsse compilant身份验证:

class WsseAuthHeader extends SoapHeader {

private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

function __construct($user, $pass, $ns = null) {
    if ($ns) {
        $this->wss_ns = $ns;
    }

    $auth = new stdClass();
    $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns); 
    $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);

    $username_token = new stdClass();
    $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns); 

    $security_sv = new SoapVar(
        new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
        SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
    parent::__construct($this->wss_ns, 'Security', $security_sv, true);
}
}



$wsse_header = new WsseAuthHeader($username, $password);
$x = new SoapClient('{...}', array("trace" => 1, "exception" => 0));
$x->__setSoapHeaders(array($wsse_header));

If you need to use ws-security with a nonce and a timestamp, Peter has posted an update version on http://php.net/manual/en/soapclient.soapclient.php#114976 of which he wrote that it did work for him: 如果你需要使用带有nonce和时间戳的ws-security,Peter已经在http://php.net/manual/en/soapclient.soapclient.php#114976上发布了一个更新版本,他写道,它确实为他:

class WsseAuthHeader extends SoapHeader
{
    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
    private $wsu_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';

    function __construct($user, $pass)
    {
        $created    = gmdate('Y-m-d\TH:i:s\Z');
        $nonce      = mt_rand();
        $passdigest = base64_encode(pack('H*', sha1(pack('H*', $nonce) . pack('a*', $created) . pack('a*', $pass))));

        $auth           = new stdClass();
        $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Nonce    = new SoapVar($passdigest, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Created  = new SoapVar($created, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wsu_ns);

        $username_token                = new stdClass();
        $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);

        $security_sv = new SoapVar(
            new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
            SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
        parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

compare as well with the details given in answer https://stackoverflow.com/a/18575154/367456 与答案https://stackoverflow.com/a/18575154/367456中给出的详细信息进行比较

The problem seems to be that the WSDL document is somehow protected (basic authentication - I don't thinkg that digest authentication is supported with SoapClient , so you'd be out of luck in this case) and that the SoapClient therefore cannot read and parse the service description. 问题似乎是WSDL文档以某种方式受到保护(基本身份验证 - 我不认为SoapClient支持摘要身份验证,因此在这种情况下你会运气不好)并且因此SoapClient无法读取和解析服务描述。

First of all you should try to open the WSDL location in your browser to check if you're presented an authentication dialog. 首先,您应该尝试在浏览器中打开WSDL位置,以检查是否显示了身份验证对话框。 If there is an authentication dialog you must make sure that the SoapClient uses the required login credentials on retrieving the WSDL document. 如果存在身份验证对话框,则必须确保SoapClient在检索WSDL文档时使用所需的登录凭据。 The problem is that SoapClient will only send the credentials given with the login and password options (as well as the local_cert option when using certificate authentication) on creating the client when invoking the service, not when fetching the WSDL (see here ). 问题是SoapClient只会在调用服务时创建客户端时使用loginpassword选项(以及使用证书身份验证时的local_cert选项)发送凭据,而不是在获取WSDL时(请参阅此处 )。 There are two methods to overcome this problem: 有两种方法可以解决这个问题:

  1. Add the login credentials to the WSDL url on the SoapClient constructor call SoapClient构造函数调用上将登录凭据添加到WSDL URL

     $client = new SoapClient( 'https://' . urlencode($login) . ':' . urlencode($password) . '@example.com/WSDL/nameofservice', array( 'login' => $login, 'password' => $password ) ); 

    This should be the most simple solution - but in PHP Bug #27777 it is written that this won't work either (I haven't tried that). 这应该是最简单的解决方案 - 但是在PHP Bug#27777中写道,这也不起作用(我没试过)。

  2. Fetch the WSDL manually using the HTTP stream wrapper or ext/curl or manually through your browser or via wget for example, store it on disk and instantiate the SoapClient with a reference to the local WSDL. 使用HTTP流包装器或ext/curl手动获取WSDL,或者通过浏览器或wget手动获取WSDL,例如,将其存储在磁盘上并使用对本地WSDL的引用来实例化SoapClient

    This solution can be problematic if the WSDL document changes as you have to detect the change and store the new version on disk. 如果WSDL文档发生更改,则此解决方案可能会出现问题,因为您必须检测更改并将新版本存储在磁盘上。

If no authentication dialog is shown and if you can read the WSDL in your browser, you should provide some more details to check for other possible errors/problems. 如果未显示身份验证对话框,并且您可以在浏览器中阅读WSDL,则应提供更多详细信息以检查其他可能的错误/问题。

This problem is definitively not related to the service itself as SoapClient chokes already on reading the service descripion document before issuing a call to the service itself. 这个问题肯定与服务本身无关,因为SoapClient在发出对服务本身的调用之前已经在读取服务描述文档时发生了扼流。

EDIT: 编辑:

Having the WSDL file locally is a first step - this will allow the SoapClient to know how to communicate with the service. 在本地拥有WSDL文件是第一步 - 这将允许SoapClient知道如何与服务进行通信。 It doesn't matter if the WSDL is directly served from the service location, from another server or is read from a local file - service urls are coded within the WSDL so SoapClient always knows where to look for the service endpoint. 无论WSDL是直接从服务位置,从另一个服务器提供服务还是从本地文件读取都无关紧要 - 服务URL在WSDL中编码,因此SoapClient始终知道在哪里查找服务端点。

The second problem now is that SoapClient has no support for the WS-Security specifications natively, which means you must extend SoapClient to handle the specific headers. 现在的第二个问题是SoapClient本身不支持WS-Security规范,这意味着您必须扩展SoapClient以处理特定的头。 An extension point to add the required behaviour would be SoapClient::__doRequest() which pre-processes the XML payload before sending it to the service endpoint. 添加所需行为的扩展点是SoapClient::__doRequest() ,它在将XML有效负载发送到服务端点之前对其进行预处理。 But I think that implementing the WS-Security solution yourself will require a decent knowledge of the specific WS-Security specifications. 但我认为自己实施WS-Security解决方案需要对特定的WS-Security规范有一定的了解。 Perhaps WS-Security headers can also be created and packed into the XML request by using SoapClient::__setSoapHeaders() and the appropriate SoapHeader s but I doubt that this will work, leaving the custom SoapClient extension as the lone possibility. 也许WS-Security标头也可以通过使用SoapClient::__setSoapHeaders()和相应的SoapHeader来创建并打包到XML请求中,但我怀疑这会起作用,留下自定义SoapClient扩展作为唯一的可能性。

A simple SoapClient extension would be 一个简单的SoapClient扩展即可

class My_SoapClient extends SoapClient
{
    protected function __doRequest($request, $location, $action, $version) 
    {
        /*
         * $request is a XML string representation of the SOAP request
         * that can e.g. be loaded into a DomDocument to make it modifiable.
         */
        $domRequest = new DOMDocument();
        $domRequest->loadXML($request);

        // modify XML using the DOM API, e.g. get the <s:Header>-tag 
        // and add your custom headers
        $xp = new DOMXPath($domRequest);
        $xp->registerNamespace('s', 'http://www.w3.org/2003/05/soap-envelope');
        // fails if no <s:Header> is found - error checking needed
        $header = $xp->query('/s:Envelope/s:Header')->item(0);

        // now add your custom header
        $usernameToken = $domRequest->createElementNS('http://schemas.xmlsoap.org/ws/2002/07/secext', 'wsse:UsernameToken');
        $username = $domRequest->createElementNS('http://schemas.xmlsoap.org/ws/2002/07/secext', 'wsse:Username', 'userid');
        $password = $domRequest->createElementNS('http://schemas.xmlsoap.org/ws/2002/07/secext', 'wsse:Password', 'password');
        $usernameToken->appendChild($username);
        $usernameToken->appendChild($password);
        $header->appendChild($usernameToken);

        $request = $domRequest->saveXML();
        return parent::__doRequest($request, $location, $action, $version);
    }
}

For a basic WS-Security authentication you would have to add the following to the SOAP-header: 对于基本的WS-Security身份验证,您必须将以下内容添加到SOAP标头:

<wsse:UsernameToken>
    <wsse:Username>userid</wsse:Username>
    <wsse:Password>password</wsse:Password>                                 
</wsse:UsernameToken>

But as I said above: I think that much more knowledge about the WS-Security specification and the given service architecture is needed to get this working. 但正如我上面所说:我认为需要更多关于WS-Security规范和给定服务架构的知识才能实现这一点。

If you need an enterprise grade solution for the whole WS-* specification range and if you can install PHP modules you should have a look at the WSO2 Web Services Framework for PHP (WSO2 WSF/PHP) 如果您需要针对整个WS- *规范范围的企业级解决方案,并且如果您可以安装PHP模块,那么您应该查看适用于PHPWSO2 Web服务框架(WSO2 WSF / PHP)

For a password digest security, you can use the following: 对于密码摘要安全性,您可以使用以下内容:

   /**
    * This function implements a WS-Security digest authentification for PHP.
    *
    * @access private
    * @param string $user
    * @param string $password
    * @return SoapHeader
    */
   function soapClientWSSecurityHeader($user, $password)
   {
      // Creating date using yyyy-mm-ddThh:mm:ssZ format
      $tm_created = gmdate('Y-m-d\TH:i:s\Z');
      $tm_expires = gmdate('Y-m-d\TH:i:s\Z', gmdate('U') + 180); //only necessary if using the timestamp element

      // Generating and encoding a random number
      $simple_nonce = mt_rand();
      $encoded_nonce = base64_encode($simple_nonce);

      // Compiling WSS string
      $passdigest = base64_encode(sha1($simple_nonce . $tm_created . $password, true));

      // Initializing namespaces
      $ns_wsse = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
      $ns_wsu = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
      $password_type = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest';
      $encoding_type = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary';

      // Creating WSS identification header using SimpleXML
      $root = new SimpleXMLElement('<root/>');

      $security = $root->addChild('wsse:Security', null, $ns_wsse);

      //the timestamp element is not required by all servers
      $timestamp = $security->addChild('wsu:Timestamp', null, $ns_wsu);
      $timestamp->addAttribute('wsu:Id', 'Timestamp-28');
      $timestamp->addChild('wsu:Created', $tm_created, $ns_wsu);
      $timestamp->addChild('wsu:Expires', $tm_expires, $ns_wsu);

      $usernameToken = $security->addChild('wsse:UsernameToken', null, $ns_wsse);
      $usernameToken->addChild('wsse:Username', $user, $ns_wsse);
      $usernameToken->addChild('wsse:Password', $passdigest, $ns_wsse)->addAttribute('Type', $password_type);
      $usernameToken->addChild('wsse:Nonce', $encoded_nonce, $ns_wsse)->addAttribute('EncodingType', $encoding_type);
      $usernameToken->addChild('wsu:Created', $tm_created, $ns_wsu);

      // Recovering XML value from that object
      $root->registerXPathNamespace('wsse', $ns_wsse);
      $full = $root->xpath('/root/wsse:Security');
      $auth = $full[0]->asXML();

      return new SoapHeader($ns_wsse, 'Security', new SoapVar($auth, XSD_ANYXML), true);
   }

To use it with PHP SoapClient, use this way : 要与PHP SoapClient一起使用,请使用以下方法:

$client = new SoapClient('http://endpoint');
$client->__setSoapHeaders(soapClientWSSecurityHeader('myUser', 'myPassword'));
// $client->myService(array('param' => 'value', ...);

I have more simple solution than extending the existing soapclient library. 我有比扩展现有soapclient库更简单的解决方案。

Step1: Create two classes to create a structure for WSSE headers 步骤1:创建两个类以创建WSSE头的结构

class clsWSSEAuth {
    private $Username;
    private $Password;
    function __construct($username, $password) {
        $this->Username=$username;
        $this->Password=$password;
    }
}

class clsWSSEToken {
    private $UsernameToken;
    function __construct ($innerVal){
        $this->UsernameToken = $innerVal;
    }
}

Step2: Create Soap Variables for UserName and Password 第二步:为UserName和Password创建Soap变量

$username = 1111;
$password = 1111;

//Check with your provider which security name-space they are using.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);

Step3: Create Object for Auth Class and pass in soap var 第3步:为Auth类创建对象并传入soap var

$objWSSEAuth = new clsWSSEAuth($objSoapVarUser, $objSoapVarPass);

Step4: Create SoapVar out of object of Auth class Step4:从Auth类的对象中创建SoapVar

$objSoapVarWSSEAuth = new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);

Step5: Create object for Token Class 步骤5:为Token Class创建对象

$objWSSEToken = new clsWSSEToken($objSoapVarWSSEAuth);

Step6: Create SoapVar out of object of Token class Step6:从Token类的对象中创建SoapVar

$objSoapVarWSSEToken = new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);

Step7: Create SoapVar for 'Security' node 步骤7:为“安全”节点创建SoapVar

$objSoapVarHeaderVal=new SoapVar($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'Security', $strWSSENS);

Step8: Create header object out of security soapvar 步骤8:从安全性soapvar创建头对象

$objSoapVarWSSEHeader = new SoapHeader($strWSSENS, 'Security', $objSoapVarHeaderVal,true, 'http://abce.com');

//Third parameter here makes 'mustUnderstand=1
//Forth parameter generates 'actor="http://abce.com"'

Step9: Create object of Soap Client Step9:创建Soap Client的对象

$objClient = new SoapClient($WSDL, $arrOptions);

Step10: Set headers for soapclient object 步骤10:为soapclient对象设置标头

$objClient->__setSoapHeaders(array($objSoapVarWSSEHeader));

Step 11: Final call to method 第11步:最后调用方法

$objResponse = $objClient->__soapCall($strMethod, $requestPayloadString);

I adopted Alain Tiemblo's excellent solution, but I use the password rather than a digest. 我采用了Alain Tiemblo的出色解决方案,但我使用的是密码而不是摘要。

    /**
    * This function implements a WS-Security authentication for PHP.
    *
    * @access private
    * @param string $user
    * @param string $password
    * @return SoapHeader
    */
    function soapClientWSSecurityHeader($user, $password)
   {
      // Creating date using yyyy-mm-ddThh:mm:ssZ format
      $tm_created = gmdate('Y-m-d\TH:i:s\Z');
      $tm_expires = gmdate('Y-m-d\TH:i:s\Z', gmdate('U') + 180); //only necessary if using the timestamp element

      // Generating and encoding a random number
      $simple_nonce = mt_rand();
      $encoded_nonce = base64_encode($simple_nonce);

      // Compiling WSS string
      $passdigest = base64_encode(sha1($simple_nonce . $tm_created . $password, true));

      // Initializing namespaces
      $ns_wsse = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
      $ns_wsu = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
      $password_type = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
      $encoding_type = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary';

      // Creating WSS identification header using SimpleXML
      $root = new SimpleXMLElement('<root/>');

      $security = $root->addChild('wsse:Security', null, $ns_wsse);

      //the timestamp element is not required by all servers
      $timestamp = $security->addChild('wsu:Timestamp', null, $ns_wsu);
      $timestamp->addAttribute('wsu:Id', 'Timestamp-28');
      $timestamp->addChild('wsu:Created', $tm_created, $ns_wsu);
      $timestamp->addChild('wsu:Expires', $tm_expires, $ns_wsu);

      $usernameToken = $security->addChild('wsse:UsernameToken', null, $ns_wsse);
      $usernameToken->addChild('wsse:Username', $user, $ns_wsse);
      $usernameToken->addChild('wsse:Password', $password, $ns_wsse)->addAttribute('Type', $password_type);
      $usernameToken->addChild('wsse:Nonce', $encoded_nonce, $ns_wsse)->addAttribute('EncodingType', $encoding_type);
      $usernameToken->addChild('wsu:Created', $tm_created, $ns_wsu);

      // Recovering XML value from that object
      $root->registerXPathNamespace('wsse', $ns_wsse);
      $full = $root->xpath('/root/wsse:Security');
      $auth = $full[0]->asXML();

      return new SoapHeader($ns_wsse, 'Security', new SoapVar($auth, XSD_ANYXML), true);
   }

To call it, use 要打电话,请使用

$client = new SoapClient('YOUR ENDPOINT');
$userid = "userid";
$password = "password"; 
$client->__setSoapHeaders(soapClientWSSecurityHeader($userid,$password));

WS Secure with digest password. WS Secure使用摘要密码。 This code work for me: 这段代码对我有用:

class WsseAuthHeader extends SoapHeader {

    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
    private $wsu_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
    private $type_password_digest= 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest';
    private $type_password_text= 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
    private $encoding_type_base64 = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary';

    private function authText($user, $pass) {
        $auth = new stdClass();
        $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Password = new SoapVar('<ns2:Password Type="'.$this->type_password_text.'">' . $pass . '</ns2:Password>', XSD_ANYXML );
        return $auth;
    }

    private function authDigest($user, $pass) {
        $created = gmdate('Y-m-d\TH:i:s\Z');
        $nonce = mt_rand();
        $enpass = base64_encode(pack('H*', sha1(pack('H*', $nonce) . pack('a*', $created) . pack('a*', $pass))));
        $auth = new stdClass();
        $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
        $auth->Password = new SoapVar('<ns2:Password Type="'.$this->type_password_digest.'">' . $enpass . '</ns2:Password>', XSD_ANYXML );
        $auth->Nonce = new SoapVar('<ns2:Nonce EncodingType="' . $this->encoding_type_base64 . '">' . base64_encode(pack('H*', $nonce)) . '</ns2:Nonce>', XSD_ANYXML);
        $auth->Created = new SoapVar($created, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wsu_ns);
        return $auth;
    }

    function __construct($user, $pass, $useDigest=true) {
        if ($useDigest) {
            $auth = $this->authDigest($user, $pass);
        }else{
            $auth = $this->authText($user, $pass);
        }
        $username_token = new stdClass();
        $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);

        $security_sv = new SoapVar(
            new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
            SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
        parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

Use: 使用:

 $client->__setSoapHeaders([new WsseAuthHeader($login, $password)]);
$client = new SoapClient("some.wsdl", array('login'    => "some_name",
                                            'password' => "some_password"));

From the php documentation 从PHP文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM