Web Service – C# Client and Apache Server Basic Authentication – Error HTTP 400 Bad Request

I write here because I’m working to transform a PHP webservice client to C# (VS2010).

Project are in Framework4 but the web service was added in VS2010 like a web service compatible with Framework2 (Web Reference with WSDL).

Actually I’m working only on a classical webservice (a Helloworld test).

With the client C# I have no problem I send a text to the web service and the web service responds by returing the text. I have no error in the Apache Server.

If I activate the basic authentification in the .htaccess apache server (host the webservice server), so in the client C# I have this error :

Exception : WebException Bad Request with state HTTP 400 : Bad Request.

In Apache error log I see this line :

[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

.

I’m sure is the credentials who are not working because when I try with a false user and password I have always the 400 Bad Request.

The code of C# Client are : // We create the 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);

.

The .htaccess : # Don’t show directory listings for URLs which map to a directory. Options -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 

.

If I delete the .htaccess file everything it’s working … but without authentication 🙁

I post also the request and response with .htaccess (not working) :

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>

.

And for finish the request without .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>

.

Thank you very much for your help on this complex problem because I searched many times without found anything to fix this issue.

“Bad Request” error for C# web service client talking to PHP server with basic authentication

I have a very basic PHP/Apache SOAP server running on a Unix box with basic authentication. I am trying to talk to it with a C# client (I’ve tried VS2010 and 2005). I create a web reference and genera

Getting 400 http bad request error while accessing WCF rest service using GET

the Exact error is System.Net.WebException: The Remote server returned an Error: (400) Bad Request. at system.Net.HttpWebRequest.GetResponse()i have a WCF rest service hosted in IIS..I have created a

WCF , The remote server returned an error: (400) Bad Request

I am getting this exception when trying to access a wcf web service. [WebException: The remote server returned an error: (400) Bad Request.] System.Net.HttpWebRequest.GetResponse() +5314029 System.Ser

The remote server returned an error: (400) Bad Request

I am getting the following errors: The remote server returned an error: (400) Bad Request Requested time out sometimes when connecting to a host using a web service. If the XML returned is 5 kb

HTTP 400 Bad Request when calling WCF Service Operation?

When I call http://localhost/TestService.svc/GetColors, I get a Http (400) Bad Request. When I run this in fiddler, I also get Bad Request. When I invoke the service through the wcf test client, it wo

Java Web Service client basic authentication

I have created a JAX-WS Web Service on top of Glassfish which requires basic HTTP authentication. Now I want to create a standalone java application client for that Web Service but I don’t have a clue

400 bad request while calling web service

I’m getting a bad request from server while calling a web service using jquery ajax post. my code looks like this :- $(#dailyEntryUpdate).click(function(){ event.preventDefault(); var values = $(#

HTTP 400 Bad Request Error with WCF Service when message size exceeds 64K

I have a .NET 4.0 WCF service. If I send a soap message larger than 64K, then I get The remote server returned an unexpected response: (400) Bad Request Error. It works fine all the way until I go o

401 error when consuming a Web service with HTTP Basic authentication using CXF

I’m trying to consume a remote Web service that uses HTTP basic authentication, using Apache CXF, within a JUnit test. The error I am getting is: javax.xml.ws.WebServiceException: Failed to access th

web service – 400 bad request

i want to consume a php Webservice from C# which is protected by htaccess. i added the Service by adding a web reference in my VS 2010. mywsfromwsdl myws = new mywsfromwsdl(); System.Net.CredentialCac

Answers

Credentials set in your code does not match credentials sent in request

Authorization: Basic bHZlaXJtYW5AYXF1aWxxxxxx1bHRpbmcuZnI6ZHluYXRlcmE3OA==

Your code set next credential for basic authentication:

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

But credentials inside Authorization Request token are:

"[email protected]:dynXXXXXXX"

(I recommend you to edit your post and remove the base64 Authentication tokens, additionally is a good idea to change your network password ASAP << DONE)

I’ve also had this problem… When you define NetworkCredentials it does not get sent in the HTTP header, and thus no ‘Authorization’ header…

What I did and it worked for me was:

I created a class that implements IClientMessageInspector and implement the BeforeSendRequest method:

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
    {
        #region Private Fields

        private string userName;

        private string password;

        #endregion

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

Then I created a class that implements IEndpointBehavior and implements the ApplyClientBehavior method:

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
    {
        #region Private Fields

        private string userName;

        private string password;

        #endregion

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

Then you need to apply this behavior to the proxy:

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

Have a look at the following:

This should do the trick… Hope it works for you!