WP7: Connecting to web services that uses authentication

No long valid, see here: https://zetitle.wordpress.com/2010/09/07/wp7-api-disappointment/

A little while ago, I was told by Microsoft that the current state of the WP7 API does not support header based authentication when dealing with web services. This put a lot of my work on hold since I do a lot of work with SharePoint and it’s web services.

For any that might be experiencing the same issues, here’s the exception I was getting:

unauthorizedexception

So, for the heck of it I wanted to see if this was true only for a small part of the API so instead of adding a service reference to the web service and letting Visual Studio generate the classes for me, I implemented a basic web service client on my own.

Turns out, this works 🙂

Here’s how I did it (Keep in mind, this is just a quick and dirty test and should be cleaned up before any production use):

First, we create the HttpWebRequest:

private static HttpWebRequest CreateWebRequest(string url, NetworkCredential credentials)
        {
            string action = "http://schemas.microsoft.com/sharepoint/soap/GetWebCollection";
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.Credentials = credentials;
            req.Headers["SOAPAction"] = action;
            req.ContentType = "text/xml;charset=\"utf-8\"";
            req.Accept = "text/xml";
            req.Method = "POST";
            return req;
        }

Then we create our SOAP envelope:

static string soapEnvelope = @"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body></soap:Body></soap:Envelope>";
private static XDocument CreateSoapEnvelope(string content)
{
    StringBuilder sb = new StringBuilder(soapEnvelope);
    sb.Insert(sb.ToString().IndexOf("</soap:Body>"), content);

    XDocument soapEnvelopeXml = XDocument.Parse(sb.ToString());

    return soapEnvelopeXml;
}

Now we insert the SOAP envelope into our web request:

private static void InsertSoapEnvelopeIntoWebRequest(XDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
    webRequest.BeginGetRequestStream((IAsyncResult asynchronousResult) =>
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        Stream postStream = request.EndGetRequestStream(asynchronousResult);
        soapEnvelopeXml.Save(postStream);
        postStream.Close();

        request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
    }, webRequest);
}

And finally a method to handle the response:

private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
    Stream streamResponse = response.GetResponseStream();
    StreamReader streamRead = new StreamReader(streamResponse);
    string responseString = streamRead.ReadToEnd();

    //do whatever with the response 

    streamResponse.Close();
    streamRead.Close();

    response.Close();
}

 

Ok, so now we have our methods – time to put them to use:

NetworkCredential credentials = new NetworkCredential("<user>", "<password>", "<domain>");
HttpWebRequest request = CreateWebRequest("<url>/_vti_bin/Webs.asmx", credentials);
XDocument soapEnvelope = CreateSoapEnvelope("<GetWebCollection xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\" />");
InsertSoapEnvelopeIntoWebRequest(soapEnvelope, request);

And the result:

webssample fiddler

Advertisements

11 Responses to WP7: Connecting to web services that uses authentication

  1. Pingback: Windows Phone 7 and NTLM authentication « zeTitle

  2. Mitchell says:

    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); is tossing an error for me and telling me to go to http://go.microsoft.com/fwlink/?linkid=106663&Version=3.7.50308.0&File=System.Windows.dll&Key=HttpWebRequest_WebException_RemoteServer

    • Frode Hus says:

      I think I’ve encountered this kind of error before and the real error message is hidden inside the exception itself. Check the Response property of the exception, most likely its a authentication error or something like that.

  3. Pingback: NTLM on Windows Phone 7 « Monsieur Rask

    • Rats says:

      Hey,

      This is really a great article. It works fine for me to get the collection of Webs but I have a Bad Request (400) error when I try to use the search Query function … did you try it ?

      Thank you !

      • Frode Hus says:

        How do you call the search query? The request needs to be rather specific – I have an implementation of it in my SharePhone project.
        I haven’t tested all of the functionality in the latest SDK version, but I’ll be doing so shortly as I’m currently building a WP7 app for SharePoint.

  4. Rats says:

    Thank you for your response. I forgot the HtmlEncode…. now everything is working fine on a .exe command line application but when I try it on the WP7 emulator i have a The remote server returned an error: NotFound. error on the EndGetResponse call… have you ever seen this error ?

    Thank you !!

    • Frode Hus says:

      I have some bad news in that regard.. I was experiencing the same issue as yourself and.. well, read my latest blog post and its all explained there.

  5. Rats says:

    Ok thank you !!

  6. Ivan says:

    I am trying to connect to Exchange web services, and it doesn’t work for me either way.
    I was able to sniff traffic via Fiddler. the communication stops after first 401 Unauthorized response.

    the same code in Silverlight 4 OOB works fine and authenticates using my credentials.

    This is the last response.

    HTTP/1.1 401 Unauthorized
    Server: Microsoft-IIS/7.5
    Set-Cookie: exchangecookie=f183cbcff347426b91378a46d9a2b4a8; expires=Fri, 02-Dec-2011 10:23:14 GMT; path=/; HttpOnly
    WWW-Authenticate: Negotiate
    WWW-Authenticate: NTLM
    X-Powered-By: ASP.NET
    Date: Thu, 02 Dec 2010 10:23:13 GMT
    Content-Length: 0
    Proxy-Support: Session-Based-Authentication

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: