2012-02-07 63 views
5

我寫在這裏,因爲我正在努力將PHP web服務客戶端轉換爲C#(VS2010)。Web服務 - C#客戶端和Apache服務器基本身份驗證 - 錯誤HTTP 400錯誤請求

項目位於Framework4中,但Web服務在VS2010中添加爲與Framework2(Web Reference with WSDL)兼容的Web服務。

其實我只在一個經典的web服務(Helloworld測試)上工作。

隨着客戶端C#我沒有問題,我發送文本到Web服務和Web服務迴應文本回應。我在Apache服務器中沒有錯誤。

如果我激活在.htaccess Apache服務器的基本認證(託管Web服務的服務器),所以在客戶端C#我有這樣的錯誤:

例外:引發WebException 錯誤請求與狀態HTTP 400:錯誤的請求。

在Apache的錯誤日誌中我看到這樣一行:

[Thu Feb 02 23:52:06 2012] [error] [client XX.XX.XX.XX] Invalid URI in request 
<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"  
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:tns="https://www.domaine.com/api/helloworld/webservices.php?wsdl" 
xmlns:types="https://www.domaine.com/api/helloworld/webservices.php?wsdl/encodedTypes" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org 
/2001/XMLSchema"> 
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<tns:bonjour><prenom xsi:type="xsd:string">Toto</prenom></tns:bonjour> 
</soap:Body> 
</soap:Envelope> 
POST /api/helloworld/webservices.php HTTP/1.1 

我敢肯定是憑據誰不工作,因爲當我嘗試使用錯誤的用戶和密碼時,我總是有400個錯誤的請求。

C#客戶端的代碼是: //我們創建webservice WebService mywebservice = new WebService();

// We define BASIC Authentication    
CredentialCache myCredentials = new CredentialCache();   
NetworkCredential netCred = new NetworkCredential("User1", "Pass1");  
myCredentials.Add(new Uri(mywebservice.Url), "Basic", netCred); 
myCredentials.PreAuthenticate = true; 
mywebservice.Credentials = myCredentials; 

// We define the UserAgent 
mywebservice.UserAgent = ".NET Framework"; 

// We call the function of webservice 
string retour = mywebservice.bonjour("Tata"); 

// We show the return 
MessageBox.Show(retour, "Retour de l'API", MessageBoxButtons.OK, MessageBoxIcon.Information); 

.htaccess: #不要顯示映射到目錄的URL的目錄列表。 期權 - 指數

# Se logue avec un compte AD 
AuthType Basic 
AuthBasicProvider ldap 
AuthName "Acces au webservice" 
AuthLDAPURL ldap://127.0.0.1:389/ou=clients,dc=domaine,dc=com?mail 
Require valid-user 

如果我刪除它的工作的.htaccess文件一切......但沒有認證:(

我還張貼請求和響應與的.htaccess(不工作):

POST https://www.domaine.com/api/login_ovh_pnp/webservices.php HTTP/1.1 
User-Agent: .NET Framework 
VsDebuggerCausalityData: uIDPo9/Tb/xbJxtKvSNra7boyJsAAAAAQcQin1OhXXXXXXXXXXX/KqROJW0w1FhAcrrhI1sGQACQAA 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl#bonjour" 
Authorization: Basic bHZlaXJtYW5AYXF1aWxhLWXXXXXXXXXXXbmcuZnI6ZHluYXRlcmE3OA== 
Host: www.domaine.com 
Content-Length: 623 
Expect: 100-continue 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:tns="https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl" 
xmlns:types="https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl 
/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<tns:bonjour> 
<prenom xsi:type="xsd:string">Tata</prenom> 
</tns:bonjour> 
</soap:Body>  
</soap:Envelope> 

===================================== 
===================================== 

HTTP/1.1 400 Bad Request 
Date: Mon, 06 Feb 2012 13:40:32 GMT 
Server: Apache 
Vary: Accept-Encoding 
Content-Length: 226 
Connection: close 
Content-Type: text/html; charset=iso-8859-1 

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>400 Bad Request</title> 
</head><body> 
<h1>Bad Request</h1> 
<p>Your browser sent a request that this server could not understand.<br /> 
</p> 
</body></html> 

而對於沒有完成的.htaccess請求:

POST https://www.domaine.com/api/login_ovh_pnp/webservices.php HTTP/1.1 
User-Agent: .NET Framework 
VsDebuggerCausalityData:  
uIDPo4r/MO3TgmdMkQiWHfkXoWwAAAAA1krYOM0NBkS9vLzFQe3Vmln8F3GXClFNrTWXL/L622YACQAA 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl#bonjour" 
Host: www.domaine.com 
Content-Length: 623 
Expect: 100-continue 
Connection: Keep-Alive 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:tns="https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl" 
xmlns:types="https://www.domaine.com/api/login_ovh_pnp/webservices.php?wsdl 
/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<tns:bonjour> 
<prenom xsi:type="xsd:string">Tata</prenom> 
</tns:bonjour> 
</soap:Body></soap:Envelope> 

===================================== 
===================================== 

HTTP/1.1 200 OK 
Date: Mon, 06 Feb 2012 13:51:31 GMT 
Server: Apache 
X-SOAP-Server: NuSOAP/0.9.5 (1.123) 
Content-Length: 575 
Vary: Accept-Encoding 
Keep-Alive: timeout=15, max=100 
Connection: Keep-Alive 
Content-Type: text/xml; charset=ISO-8859-1 

<?xml version="1.0" encoding="ISO-8859-1"?> 
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"> 
<SOAP-ENV:Body> 
<ns1:bonjourResponse xmlns:ns1="https://supervision.dynatera.net/api/login_ovh_pnp/webservices.php?wsdl"> 
<return xsi:type="xsd:string">Bonjour Tata</return></ns1:bonjourResponse> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

非常感謝您對這個複雜問題的幫助,因爲我搜索了很多次,但沒有找到任何解決此問題的方法。

+0

你可以使用soapui調用安全服務嗎? – davidfrancis 2012-02-07 23:51:49

+0

發佈編輯刪除用戶/密碼 – 2012-02-13 11:44:37

回答

0

憑據在你的代碼不匹配的請求發送憑據設置

Authorization: Basic bHZlaXJtYW5AYXF1aWxxxxxx1bHRpbmcuZnI6ZHluYXRlcmE3OA== 

基本身份驗證代碼中設置下一個證書:

// We define BASIC Authentication    
CredentialCache myCredentials = new CredentialCache();   
NetworkCredential netCred = new NetworkCredential("User1", "Pass1"); 

但授權請求令牌裏面憑據:

"[email protected]:dynXXXXXXX" 

(我建議你編輯你的文章並刪除base64認證令牌,另外是一個好主意,改變你的網絡密碼儘快< < DONE)

4

我也有這個問題...... 當你定義NetworkCredentials它不會在HTTP頭中發送,因此沒有「授權」頭......

我所做的,它的工作對我來說是:

我創建了一個實現IClientMessageInspector一類,並實現BeforeSendRequest方法:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.ServiceModel.Dispatcher; 
using System.ServiceModel.Channels; 

namespace BasicAuth 
{ 
    public sealed class MessageHttpHeaderInspector : IClientMessageInspector 
    { 
     private string userName; 
     private string password; 

     #region Constructor 

     public MessageHttpHeaderInspector(string userName, string password) 
     { 
      this.userName = userName; 
      this.password = password; 
     } 

     #endregion 

     #region IClientMessageInspector Members 

     public void AfterReceiveReply(ref Message reply, object correlationState) 
     { 
      //throw new NotImplementedException(); 
     } 

     public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel) 
     { 
      HttpRequestMessageProperty httpRequest; 

      if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name)) 
      { 
       httpRequest = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; 
      } 
      else 
      { 
       httpRequest = new HttpRequestMessageProperty(); 
       request.Properties.Add(HttpRequestMessageProperty.Name, httpRequest); 
      } 

      if (httpRequest != null) 
      { 
       string credentials = this.CreateBasicAuthenticationCredentials(this.userName, this.password); 
       httpRequest.Headers.Add(System.Net.HttpRequestHeader.Authorization, credentials); 
      } 

      return request; 
     } 

     #endregion 

     #region Private Worker Methods 

     private string CreateBasicAuthenticationCredentials(string userName, string password) 
     { 
      string returnValue = string.Empty; 
      string base64UsernamePassword = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))); 

      returnValue = String.Format("Basic {0}", base64UsernamePassword); 

      return returnValue; 
     } 

     #endregion 
    } 
} 

然後,我創建了一個實現IEndpointBehavior並實現ApplyClientBehavior方法的類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.ServiceModel; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 

namespace BasicAuth 
{ 
    public sealed class CustomEndpointCallBehavior : IEndpointBehavior 
    { 
     private string userName;  
     private string password; 

     #region Constructor 

     public CustomEndpointCallBehavior(string userName, string password) 
     { 
      this.userName = userName;  
      this.password = password; 
     } 

     #endregion 

     #region IEndpointBehavior Members 

     public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
     { 
      //throw new NotImplementedException(); 
     } 

     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
     { 
      clientRuntime.MessageInspectors.Add(new MessageHttpHeaderInspector(this.userName, this.password)); 
     } 

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
     { 
      //throw new NotImplementedException(); 
     } 

     public void Validate(ServiceEndpoint endpoint) 
     { 
      //throw new NotImplementedException(); 
     } 

     #endregion 
    } 
} 

然後,你需要這種行爲適用於代理:

mywebservice.Endpoint.Behaviors.Add(new CustomEndpointCallBehavior("User1", "Pass1")); 

看一看下面:

這應該做的伎倆...... 希望工程爲您服務!

+1

非常感謝。這工作沒有問題。 – 2013-03-12 08:35:19

相關問題