2011-07-05 95 views
0

我有一個關於用PHP編寫的web服務的問題。在.NET客戶端上使用PHP webservice的問題

要實例SoapClient使用PHP,我通過以下參數對SoapClient方法在PHP這樣的:

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

要調用與PHP web服務方法,能正常工作。但是我的同事在使用.NET發送證書時遇到了問題。

有誰知道這是如何通過.NET?

更新,淨客戶端配置

<basicHttpBinding> 
    <binding name="webserviceControllerBinding"> 
     <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Basic"/> 
     </security> 
    </binding> 
</basicHttpBinding> 

而在代碼:

client.ClientCredentials.UserName.UserName = "username"; 
client.ClientCredentials.UserName.Password = "password"; 

更新2:

建立所述客戶端(在PHP)

$client = new 
SoapClient("http://***.***.***/********/httpdocs/webservice/wsdl?wsdl", 
    array(
     'uri'  => "http://***.***.***/***/httpdocs/webservice/webservice", 
     'login' => "*****", 
     'password' => "*****" 
)); 

處理請求並引用該類的服務器。

public function webservice() 
    parent::__construct(); 
    ini_set('soap.wsdl_cache_enabled', 0); 
    $this->presenter  = "NONE"; 
    $server    = new SoapServer("http://***.***.***/***/httpdocs/webservice/wsdl?wsdl", array('uri' => "http://***.***.***/")); 

    $server->setClass( "Model_Webservice"); 
    $server->handle(); 

而webservice類中的這一塊處理用戶名和密碼認證。

class Model_Webservice extends Object_Database 
{ 

public function __construct() 
{ 
    parent::__construct(); 

    $accesslog  = Log::factory('file', $this->config->log->access , 'ACCESS LOG'); 

    if(!isset($_SERVER['PHP_AUTH_USER']) || trim($_SERVER['PHP_AUTH_USER']) == "") 
    { 
    $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] no username supplied"); 
    throw new SOAPFault("Authentication failed - reason: no username supplied", 401); 
    } 
    elseif(!isset($_SERVER['PHP_AUTH_PW']) || trim($_SERVER['PHP_AUTH_PW']) == "") 
    { 
    $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] no password supplied"); 
    throw new SOAPFault("Authentication failed - reason: no password supplied", 401); 
    } 
    else 
    { 
    $user = new User(null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); 

    if($user->getId() > 0) 
    { 
     $accesslog->log("[approved] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] User logged in"); 
    } 
    if(!$user->getId() > 0) 
    { 
     $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] incorrect username and password combination"); 
     throw new SOAPFault("Authentication failed - reason: incorrect username and password combination", 401); 
    } 
    } 
} 

更新3

我基於調整後的配置收到以下錯誤消息

<bindings> 
     <basicHttpBinding> 
      <binding name="webserviceControllerBinding"> 
       <security mode="Message">     
        <message clientCredentialType="UserName" algorithmSuite="Default" /> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 

BasicHttp結合要求BasicHttpBinding.Security.Message.ClientCredentialType相當於用於安全消息的BasicHttpMessageCredentialType.Certificate憑證類型。 爲UserName憑證選擇Transport或TransportWithMessageCredential安全性。'

我不想使用證書或https。

+0

他們如何指定的憑據和你使用的身份驗證機制? – jgauffin

+0

我必須說,如果我關閉PHP服務器的安全性,我們可以使用.NET調用Web服務。但是,這是其他程序員使用: <綁定名稱= 「webserviceControllerBinding」> <安全模式= 「TransportCredentialOnly」> <傳輸clientCredentialType = 「基本」/> client.ClientCredentials .UserName.UserName =「username」; client.ClientCredentials.UserName.Password =「password」; –

+0

總是添加代碼作爲您問題的更新。否則將不可能遵循它。 – jgauffin

回答

1

我建議使用類似Fiddler這樣的工具來捕獲正在運行的PHP客戶端和您的非功能.NET客戶端發送的實際SOAP XML數據。

如果您比較兩個請求,您很有可能會看到其中的差異,並能夠解決問題。

希望有所幫助。

+0

我已經安裝了Fiddler,但我似乎無法趕上請求發送到服務器。只有反應正在顯示。 –

+0

很奇怪。如果你能看到迴應,我原以爲你應該能夠看到請求。 – Spudley

1

我敢打賭,.NET中的WCF不會發送身份驗證頭(默認情況下),除非從Web服務獲取一個質詢。

如果未提供用戶名或密碼,則應返回HTTP狀態碼401,如果用戶名/密碼不正確,則應返回http狀態碼403。

換句話說:刪除SoapException並返回正確的HTTP狀態碼。

更新爲響應更新3

嘛。這個異常與它是一個PHP web服務無關。這是一個完全不同的問題。由於在沒有證書的情況下使用BASIC身份驗證會在CLEAR TEXT中發送密碼,因此會引發錯誤。

我會切換到像DIGEST身份驗證更安全的東西。

+0

說實話,它返回SOAPFault:身份驗證失敗 - 原因:沒有提供用戶名。這意味着它沒有通過第一個用戶名/密碼檢查。所以.NET甚至沒有向web服務發送任何東西。 –

+0

他們在.NET中遇到了什麼樣的異常呢?你必須提供所有相關信息 – jgauffin

0
MessageHeader header= MessageHeader.CreateHeader("My-CustomHeader","http://myurl","Custom Header."); 

     using (phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient client = new phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient()) 
     { 
      using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
      { 
       OperationContext.Current.OutgoingMessageHeaders.Add(header); 
       HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty(); 
       byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("username:password");      
       httpRequestProperty.Headers.Add("Authorization: Basic "+ System.Convert.ToBase64String(toEncodeAsBytes));            
       OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty; 
       string str = client.getVacanciesReference(""); 
      }         
     } 

以上代碼已經解決了我的問題(我用這些網址,供參考)

http://caught-in-a-web.blogspot.com/2008/04/how-to-add-custom-http-header-in-wcf.html http://en.wikipedia.org/wiki/Basic_access_authentication

相關問題