2012-02-07 30 views
5

Tôi viết ở đây vì tôi đang làm việc để chuyển đổi máy khách web PHP thành C# (VS2010).Dịch vụ Web - C# Máy khách và Xác thực Cơ sở Máy chủ Apache - Lỗi HTTP 400 Yêu cầu Xấu

Dự án nằm trong Framework4 nhưng dịch vụ web đã được thêm vào VS2010 như dịch vụ web tương thích với Framework2 (Tham khảo web với WSDL).

Thực ra tôi chỉ làm việc trên dịch vụ web cổ điển (thử nghiệm của Helloworld).

Với ứng dụng khách C# Tôi không gặp vấn đề gì khi gửi văn bản đến dịch vụ web và dịch vụ web phản hồi bằng cách lưu lại văn bản. Tôi không có lỗi trong máy chủ Apache.

Nếu tôi kích hoạt xác thực cơ bản trong máy chủ apache .htaccess (đăng cai máy chủ webservice), vì vậy trong client C# Tôi có lỗi này:

Ngoại lệ: WebException Bad Request với trạng thái HTTP 400: Bad Request .

Trong Apache log lỗi tôi thấy dòng này:

[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 

.

Tôi chắc chắn là thông tin đăng nhập không hoạt động vì khi tôi thử với người dùng và mật khẩu giả, tôi luôn có Yêu cầu không hợp lệ 400.

Mã của C# Khách hàng là: // Chúng tôi tạo 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: # Không hiển thị danh sách thư mục cho URL ánh xạ tới thư mục. Tùy chọn -Indexes

# 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 

.

Nếu tôi xóa tất cả mọi thứ .htaccess tập tin nó làm việc ... nhưng không xác thực :(

Tôi cũng gửi yêu cầu và phản ứng với .htaccess (không hoạt động):.

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> 

Và đối với kết thúc theo yêu cầu mà không cần .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> 

.

Cảm ơn bạn rất nhiều vì đã giúp bạn về vấn đề phức tạp này vì tôi đã tìm kiếm nhiều lần mà không tìm thấy bất kỳ điều gì để khắc phục vấn đề này.

+0

Bạn có thể gọi cho dịch vụ an toàn bằng soapui không? – davidfrancis

+0

Bài chỉnh sửa để xóa người dùng/mật khẩu –

Trả lời

0

Credentials đặt trong mã của bạn không phù hợp với thông tin được gửi trong yêu cầu

Authorization: Basic bHZlaXJtYW5AYXF1aWxxxxxx1bHRpbmcuZnI6ZHluYXRlcmE3OA== 

đang thiết lập của bạn chứng tiếp theo để xác thực cơ bản:

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

Nhưng thông tin bên trong Authorization Request thẻ là:

"[email protected]:dynXXXXXXX" 

(Tôi khuyên bạn nên chỉnh sửa bài đăng của mình và xóa base64 thẻ xác thực, bổ sung là một ý tưởng tốt để thay đổi mật khẩu mạng của bạn càng sớm càng tốt < < HOÀN THÀNH)

4

Tôi cũng đã có vấn đề này ... Khi bạn xác định NetworkCredentials nó không được gửi trong tiêu đề HTTP, và do đó không 'phép' tiêu đề ...

những gì tôi đã làm và nó làm việc đối với tôi là:

tôi tạo ra một lớp mà thực hiện IClientMessageInspector và thực hiện các phương pháp 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 
    } 
} 

Sau đó, tôi đã tạo ra một lớp mà thực hiện IEndpointBehavior và thực hiện các phương pháp 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 
    } 
} 

Sau đó, bạn cần phải áp dụng hành vi này đến proxy:

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

Hãy nhìn vào những điều sau đây:

này nên làm các trick ... Hy vọng nó sẽ làm việc cho bạn!

+1

Cảm ơn một triệu. Điều này làm việc mà không có vấn đề gì. –

Các vấn đề liên quan