2009-06-04 4 views
28

Próbuję połączyć się z usługą internetową, która jest chroniona hasłem, a adres URL to https. Nie mogę wymyślić, jak przeprowadzić uwierzytelnianie, zanim skrypt wyśle ​​żądanie. Wygląda na to, że składa zapytanie, gdy tylko zdefiniuję usługę. Na przykład, jeśli kładę się:Połączenie z usługą WWW chronioną przez WS-Security za pomocą PHP

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

a następnie przejść do witryny w przeglądarce, otrzymuję:

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 

Gdy próbuję definiowanie usługę jako serwer mydło, jak:

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

uzyskać:

<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> 

nie mam próbowałem wysłać surową kopertę żądania jeszcze, aby zobaczyć, co zwraca serwer, ale może to być obejście problemu. Miałem jednak nadzieję, że ktoś może mi powiedzieć, jak mogę to skonfigurować za pomocą wbudowanych klas php. Próbowałem dodać do tablicy "userName" i "password", ale to nie było dobre. Problem polega na tym, że nie mogę nawet stwierdzić, czy w ogóle dotarłem do strony zdalnej, nie mówiąc już o tym, czy odmawia ona żądania.

Odpowiedz

27

Problem wydaje się, że dokument WSDL jest w jakiś sposób chronione (uwierzytelnianie podstawowe - Nie thinkg które trawią uwierzytelnianie jest obsługiwane SoapClient, więc chcesz mieć pecha w w tym przypadku) i dlatego SoapClient nie może odczytać i przeanalizować opisu usługi.

Przede wszystkim należy spróbować otworzyć lokalizację WSDL w przeglądarce, aby sprawdzić, czy wyświetlane jest okno dialogowe uwierzytelniania. Jeśli istnieje okno dialogowe uwierzytelniania, należy się upewnić, że SoapClient używa wymaganych poświadczeń logowania podczas pobierania dokumentu WSDL. Problem polega na tym, że SoapClient wysyła tylko poświadczenia podane z opcjami login i password (jak również z opcją local_cert podczas korzystania z uwierzytelniania certyfikatów) podczas tworzenia klienta podczas wywoływania usługi, a nie podczas pobierania WSDL (patrz here). Istnieją dwa sposoby rozwiązania tego problemu:

  1. dodać dane logowania do url WSDL na wezwanie SoapClient konstruktora

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

    Powinno to być najprostsze rozwiązanie - ale w PHP Bug #27777 jest napisane, że to też nie zadziała (nie próbowałem tego).

  2. Fetch WSDL ręcznie za pomocą strumienia HTTP opakowanie lub ext/curl lub ręcznie za pośrednictwem przeglądarki lub poprzez wget na przykład zapisać go na dysku i instancję SoapClient z odniesieniem do lokalnych WSDL.

    To rozwiązanie może być problematyczne, jeśli dokument WSDL zmienia się, ponieważ trzeba wykryć zmianę i zapisać nową wersję na dysku.

Jeśli nie jest wyświetlane okno dialogowe uwierzytelniania i można odczytać plik WSDL w przeglądarce, należy podać więcej szczegółów, aby sprawdzić inne możliwe błędy/problemy.

Ten problem nie jest ostatecznie związany z samą usługą, ponieważ dławiki już czytają dokument opisujący usługę przed wydaniem wywołania do samej usługi.

EDIT:

Posiadające pliku WSDL lokalnie jest pierwszym krokiem - pozwoli to SoapClient umieć komunikować się z obsługi. Nie ma znaczenia, czy plik WSDL jest obsługiwany bezpośrednio z lokalizacji usługi, z innego serwera, czy jest odczytywany z pliku lokalnego - adresy URL usług są kodowane w obrębie WSDL, więc SoapClient zawsze wie, gdzie szukać punktu końcowego usługi.

Drugi problem polega teraz na tym, że nie obsługuje natywnie specyfikacji WS-Security, co oznacza, że ​​należy rozszerzyć zakres SoapClient, aby obsłużyć określone nagłówki. Punktem rozszerzającym, który doda wymagane zachowanie, będzie SoapClient::__doRequest(), który wstępnie przetwarza ładunek XML przed wysłaniem go do punktu końcowego usługi. Ale myślę, że samodzielne wdrożenie rozwiązania WS-Security będzie wymagało przyzwoitej znajomości specyficznych specyfikacji WS-Security. Być może nagłówki WS-Security można również utworzyć i spakować do żądania XML za pomocą SoapClient::__setSoapHeaders() i odpowiednich SoapHeader s, ale wątpię, że to zadziała, pozostawiając niestandardowe rozszerzenie SoapClient jako jedyną możliwość.

Prosty SoapClient rozszerzenie byłoby

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); 
    } 
} 

Dla podstawowego uwierzytelniania WS-Security trzeba by dodać następujące SOAP-Header:

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

Ale jak powiedziałem powyżej: Myślę, że potrzeba dużo więcej wiedzy na temat specyfikacji WS-Security i danej architektury usług, aby to zadziałało.

Jeśli potrzebujesz rozwiązania klasy Enterprise dla całego zakresu specyfikacji WS- * i czy można zainstalować moduły PHP należy spojrzeć na WSO2 Web Services Framework for PHP (WSO2 WSF/PHP)

+0

Wow. Dzięki za świetny początek. Okay, więc mówiąc dokładniej, nie jest to uwierzytelnianie http. Jeśli przejdę do adresu URL, nastąpi przekierowanie do logowania, a następnie mogę zobaczyć usługę. W dokumentacji tej usługi mówi, że uwierzytelnianie użytkownika powinno być ustawione w nagłówku SOAP, ale oczywiście widzę, jak to zrobić w PHP. (nazywa się to WS-security, dzieje się to w moim ostatnim wyszukiwaniu w Google i wydaje mi się, że nie jest dobrze zaimplementowane w PHP.) Jeśli znasz sposób na ustawienie nagłówka, lub użyj innej metody, na przykład curl, aby uzyskać usługę i następnie przekazanie tego do SoapClient, byłoby oświecające. – Anthony

+0

Oh! Szybkie pytanie ... Więc skopiowałem usługę do pliku na moim serwerze, jestem w stanie ją skonfigurować. Wciąż nie jestem pewien, jak się w tym poruszać. Ale czy mówiłeś, że usługa będzie działać, gdy nie znajduje się w jej faktycznym miejscu? – Anthony

+1

Poszerzyłem odpowiedź o niektóre punkty dotyczące manipulacji przy pomocy WS-Security i protokołu SOAP za pomocą SoapClient. –

0
$client = new SoapClient("some.wsdl", array('login' => "some_name", 
              'password' => "some_password")); 

From the php documentation

+0

To była pierwsza rzecz, ja, ten sam błąd, jak pamiętam. Uwierzytelnienie trafia do nagłówka (zgodnie z dokumentacją dla tej konkretnej usługi) i nie sądzę, żebym mógł zmienić nagłówek do czasu zdefiniowania klienta, ale do tego czasu zostanie zgłoszony błąd. – Anthony

6

mam więcej niż proste rozwiązanie rozszerzenie istniejącego SoapClient biblioteka.

Krok 1: Utwórz dwie klasy, aby utworzyć strukturę nagłówków 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; 
    } 
} 

Krok 2: Tworzenie zmiennych mydło do nazwa użytkownika i hasło

$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); 

Krok 3: Tworzenie obiektu dla Auth klasy i przekazać na mydło var

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

Krok 4: Utwórz SoapVar z obiektu klasy Auth

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

Krok 5: Tworzenie obiektu za Reklamowe klasy

$objWSSEToken = new clsWSSEToken($objSoapVarWSSEAuth); 

Step6: Tworzenie SoapVar z przedmiotu Reklamowe klasy

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

Step7: Tworzenie SoapVar do węzła 'Bezpieczeństwo'

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

Krok 8: Utwórz nagłówek object z bezpieczeństwem 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: Tworzenie obiektu klienta SOAP

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

Step10: Ustaw nagłówki soapclient obiektu

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

Krok 11: Ostateczne wezwanie do metody

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

Po prostu ex wydają się SoapHeader stworzyć WSSE compilant uwierzytelniania:

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)); 

Jeśli trzeba użyć WS-Security z nonce i datownika, Peter opublikował wersję aktualizacji na http://php.net/manual/en/soapclient.soapclient.php#114976 których pisał, że to zrobił dla niego pracować:

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); 
    } 
} 

porównać także z danymi podanymi w odpowiedzi https://stackoverflow.com/a/18575154/367456

+0

To jest najlepsza odpowiedź. –

15

o hasło strawienia bezpieczeństwa można użyć Follo Skrzydło:

/** 
    * 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); 
    } 

Aby korzystać z PHP SoapClient używać w ten sposób:

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

Chciałbym dać ci więcej przebojów! To działało idealnie. – Ariel

+0

Dlaczego używasz funkcji 'pack()'? Nie robi nic. Usunąłem go bez zmiany wyniku, z wyjątkiem dodania "true" do wywołania funkcji 'sha1()'. – Ariel

+0

Nie pamiętam dokładnie, ale czytałem i stosowałem pewne specyfikacje techniczne dotyczące tego tematu. Nienawidzę SOAP, więc nie poszedłem dalej. W każdym razie ciesz się :-). –

0

przyjąłem doskonałe rozwiązanie Alain Tiemblo, ale używam hasło zamiast trawienia.

/** 
    * 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); 
    } 

nazywać go użyć

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

WS zabezpieczyć strawienia hasło. Ta praca kod dla mnie:

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); 
    } 
} 

Zastosowanie:

$client->__setSoapHeaders([new WsseAuthHeader($login, $password)]); 
Powiązane problemy