Basic Auth Webservice Client with .NET

If a webservice requires basic http authentication (like the ones from wortschatz.uni-leipzig.de) and it doesn’t respond to a request without authentication with the proper 401 response (for example with a 500), you cannot use this service with the standard .NET client, because this client doesn’t send the header with the first request. Only after a 401 response, the header is sent.

After a lot of trial and error and searching the internet, I finally found this simple solution:

http://mark.michaelis.net/Blog/default.aspx?month=2005-03

Instead of changing the autogenerated class, I would subclass the generated one and use the new class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Webservice : de.uni_leipzig.wortschatz.BaseformService {
   protected override System.Net.WebRequest GetWebRequest(Uri uri) {
     HttpWebRequest request;
     request = (HttpWebRequest)base.GetWebRequest(uri);
 
     if (PreAuthenticate) {
       NetworkCredential networkCredentials =
       Credentials.GetCredential(uri, "Basic");
 
       if (networkCredentials != null) {
         byte[] credentialBuffer = new UTF8Encoding().GetBytes(
           networkCredentials.UserName + ":" +
           networkCredentials.Password);
         request.Headers["Authorization"] =
           "Basic " + Convert.ToBase64String(credentialBuffer);
       } else {
         throw new ApplicationException("No network credentials");
       }
     }
     return request;
   }
}

The client can then be configured like this:

1
2
3
4
5
6
NetworkCredential netCredential = new NetworkCredential("anonymous","anonymous");
Uri uri = new Uri(ws.Url);
ICredentials credentials = netCredential.GetCredential(uri, "Basic");
ws.Credentials = credentials;
// Be sure to set PreAuthenticate to true or else authentication will not be sent.
ws.PreAuthenticate = true;

Share this:
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Buzz
  • LinkedIn
  • Technorati

5 Responses to “Basic Auth Webservice Client with .NET”

  1. kunal Says:

    Hi sir,

    I am calling a webservice in asp.net by http basic authentication(RFC2617) but unable to do so despite numerous attempts.

    my code is(not working for me):

    MyService service = new MyService();
    service.Credentials = new NetworkCredential(“username”, “password”);
    service.PreAuthenticate = true;

    and
    MyService service = new MyService();
    NetworkCredential netCredential = new NetworkCredential(“username”, “password”);
    Uri uri = new Uri(service.Url);
    service.Credentials = netCredential.GetCredential(uri, “Basic”);
    service.PreAuthenticate = true;

    My client has given me document as follows how to call webservice:

    please read about RFC2617 and how to implement it.
    It’s clearly mentioned on page 110 of the Integration Document:
    Technology Partner Authentication
    “Technology Partner”, in the context of this document, means an authorized
    “Account” on the IRCTC site authorized to consume the web services. The username and password of the “Technology Partner” is set in the http header.

    NOTE: IRCTC Webservices follows strictly, the HTTP BASIC Authentication
    (RFC2617), so the same has to be followed by the integrating parties
    whether on Java/.NET or any other platform.

    i try to do what Mr. Mark written on his blog but it gives me error: no suitable method find to override.

    http://mark.michaelis.net/Blog/CallingWebServicesUsingBasicAuthentication.aspx

    plz sir help me.

    Thanks & Regards
    Kunal Tilak

  2. Kai Says:

    I can not help you here. Just be sure that your Service implements System.Web.Services.Protocols.SoapHttpClientProtocol, which should be the case for automatically created clients.

  3. Geeko Says:

    Hallo Kai,

    über trial & errror bin ich zwar schon lange hinaus, es will aber immer noch nicht funktionieren.
    Ich versuch hier genauso wie du eine Verbindung zu dem Uni-Leipzig Server herzustellen um Synonyme abzufragen. Aber es will einfach nicht.
    Die Subclass hab ich so von dir übernommen. Versuch ich aber eine Verbindung zum Server aufzubauen, will er immer noch ein Passwort bzw. Benutzername.

    Meinst du könntest mir deine Implementierung in Form einer Konsolenanwendung zukommen lassen oder mir sagen was daran falsch ist?:
    static void Main(string[] args)
    {
    ServiceOverviewService sos =
    new ServiceOverviewService();

    NetworkCredential netCredential = new NetworkCredential(“anonymous”, “anonymous”);
    Uri uri = new Uri(sos.Url);
    ICredentials credentials = netCredential.GetCredential(uri, “Basic”);
    sos.Credentials = credentials;
    // Be sure to set PreAuthenticate to true or else authentication will not be sent.
    sos.PreAuthenticate = true;

    RequestParameter param = new RequestParameter();
    param.corpus = “Internet”; // whatever …

    ResponseParameter response = sos.execute(param);
    }

    Gruß Geeko

  4. Kai Says:

    Hi Geeko,

    sorry, das ist zu lange her, da müsste ich mich noch mal neu reindenken. Vielleicht haben die auch auf der Wortschatz-Seite etwas geändert, da würde ich mal nachfragen. Ich habe den Dienst schon ewig nicht mehr benutzt und kann noch nicht mal auf die Schnelle sagen, ob meine Implementierung noch funktioniert, weil ich gar kein Windows-System mehr laufen habe (Java hat bei dem Projekt am Ende doch das Rennen gemacht ;-) ).

    Viele Grüße,

    Kai

  5. Geeko Says:

    Hi Kai,

    trotzdem danke für die schnelle Antwort :-)

    Grüße
    Geeko

Leave a Reply