Come utilizzare un servizio Web WCF che utilizza la validation del nome utente personalizzata con una pagina PHP?

Sto facendo fatica a consumare un servizio Web WCF sicuro da un sito PHP. Le mie conoscenze in PHP sono limitate, ho trovato vari esempi sul Web ma non sono riuscito a farli funzionare ancora.

Ho un'applicazione Silverlight che consuma anche questo WebService e funziona perfettamente. Ma quando eseguo il sito PHP, ottengo questo errore:

MessageSecurityException: il processre di sicurezza non è riuscito a trovare un'intestazione di sicurezza nel messaggio. Ciò potrebbe essere dovuto al fatto che il messaggio è un errore non protetto o perché esiste una corrispondenza non binding tra le parti comunicanti. Ciò può verificarsi se il servizio è configurato per la sicurezza e il client non sta utilizzando la sicurezza.

Ho anche provato a cambiare CustomBinding in BasicHttpBinding. Quando lo faccio, il validatore del nome utente personalizzato non viene più chiamato. Ma, usando basicHttpBinding e rimuovendo la validation delle credenziali sul mio servizio WCF "funziona" (oltre al fatto che non è sicuro). Quindi il problema sembra correlato al messaggio di sicurezza.

Qualcuno potrebbe darmi un esempio di lavoro o un tutorial che potrebbe aiutarmi a far funzionare questa pagina PHP?

Ecco il mio codice PHP:

$options = arrays( 'soap_version' => SOAP_1_1, 'exceptions' => true, 'trace' => 1, 'cache_wsdl' => WSDL_CACHE_NONE, 'Username' => 'MyUserName', 'password' => 'MyPassword'); $client = new SoapClient('https://UrlToService/Service.svc?wsdl', $options); try { $phpresponse = $client->Get(); print $phpresponse->GetResult->Version; echo "</b><BR/><BR/>"; } catch(Exception $e) { echo "<h2>Exception Error!</h2></b>"; echo $e->getMessage(); echo "<BR/><BR/>"; } 

Configurazione WCF

 <behavior name="sslBehavior"> <serviceMetadata httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.ServiceUserNameValidator, MyNamespace" /> </serviceCredentials> <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" /> </behavior> <customBinding> <binding name="sslCustomBinding"> <security authenticationMode="UserNameOverTransport" includeTimestamp="true" allowInsecureTransport="true"> <localServiceSettings maxClockSkew="00:10:00" /> <localClientSettings maxClockSkew="00:10:00" /> <secureConversationBootstrap /> </security> <textMessageEncoding messageVersion="Soap11" /> <httpsTransport /> </binding> </customBinding> <service behaviorConfiguration="sslBehavior" name="MyNamespace.Services.Service"> <endpoint address="" binding="customBinding" bindingConfiguration="sslCustomBinding" contract="MyNamespace.ServiceContracts.IService" /> <host> <baseAddresses> <add baseAddress="https://UrlToService/Services/" /> </baseAddresses> </host> </service> 

Ho risolto il problema. Ho dovuto estendere la class "SoapHeader" in PHP per renderla compatibile con lo standard WS-Security.

Ecco la soluzione:

PHP Header class

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

Chiamata client PHP

 $options = arrays( 'soap_version' => SOAP_1_1, 'exceptions' => true, 'trace' => 1, 'wdsl_local_copy' => true ); $username = "MyUser"; $password = "MyPassword"; $wsse_header = new WsseAuthHeader($username, $password); $client = new SoapClient('https://UrlToService/Service.svc?wsdl', $options); $client->__setSoapHeaders(arrays($wsse_header)); try { $phpresponse = $client->Get(); print $phpresponse->GetResult->Version; echo "</b><BR/><BR/>"; } catch(Exception $e) { echo "<h2>Exception Error!</h2></b>"; echo $e->getMessage(); } 

Spero che aiuti qualcun altro!

Grazie a Chris: Connessione al servizio Web protetto da WS-Security con PHP

SOAP è un po 'divertente con l'authentication (o può essere), ho usato il metodo da http://www.php.net/manual/en/soapclient.soapclient.php#101503 vedi commento da, faebu a faebu punto ch 21- Dic-2010 02:58 per aver fatto esattamente questo alcune volte … potrebbe essere d'aiuto

In pratica utilizza CURL per passare le credenziali di authentication … potrebbe / non funzionare per te!