Click here to Skip to main content
15,867,594 members
Articles / Security / Encryption
Tip/Trick

Trouble with HttpWebRequest Authorization

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
25 Apr 2014CPOL1 min read 27.7K   5   2
RFC 2617 on the net-platform

Introduction

The HttpWebRequest class is very useful to work with internet data, but it got some problems. When calling different secure endpoints, only the first is working and for the rest the auth is failing. To be honest, it is a bug in the complete net-platform, and I hope it gets fixed sooner than later.

Background

In digest authorization on Windows Phone 8 is a problem which led me to some trouble and headaches before I figured out the solution.

After some days, I found the solution on stackoverflow which got also mentioned on the MSDN blog.

To understand digest authorization, read this.

Using the Code

The provided code consists of three functions. Hint: It isn't a project, but only the 3 functions.

First creating a request, then writing the soap-message, which got refused and then starting the auth with a own digest. In the end is the link to the stackoverflow postings in which a detailed solution is provided.

C#
private void CreateCall()
{
    Uri uri = new Uri(m_SoapEndPoint,UriKind.Absolute);
    HttpWebRequest request = WebRequest.Create( uri ) as HttpWebRequest;
    request.Method = "POST";
    request.UserAgent = "UPnP/1.0 Client 1.0";
    request.Headers["SOAPACTION"] = NameSpace + "#" + SoapMethod;
    request.ContentType = "text/xml;charset=\"utf-8\"";
    request.AllowAutoRedirect = false;
    request.UseDefaultCredentials = false;// of the currently logged on user.

    //works only for the first endpoint
    //request.Credentials = new NetworkCredential( Settings.User, Settings.Password );

    if( Nonce.Length > 0 )//if the call is restarted there is a nonce
    {
        String sAuthentification = GetAuthorizationMd5();
        request.Headers[HttpRequestHeader.Authorization] = sAuthentification;
    }

    // Make async call for request stream. Callback will be called on a background thread.
    IAsyncResult asyncResult = request.BeginGetRequestStream(OnRequestStream, request);
}

 private void OnRequestStream( IAsyncResult ar )
    {
        try
        {
            if( ar.IsCompleted )
            {
                HttpWebRequest request = (HttpWebRequest) ar.AsyncState;
                using( Stream requestStream = request.EndGetRequestStream( ar ) )
                {
                    using( StreamWriter streamWriter = new StreamWriter( requestStream ) )
                    {

                        // Write to the request stream.
                        streamWriter.Write( m_SoapBody );

                            streamWriter.Flush();
                            streamWriter.Close();
                        }
                    }
                    // Make async call for response. Callback will be called on a background thread.
                    IAsyncResult result = request.BeginGetResponse( OnResponseStream, request );
                }
            }
        }
        catch (WebException we)
        {
            m_bRunning = false;
            Status = "OnRequestStream mit WebException: " + we.Message;
            MessageBox.Show( Status );
        }
    }

private void OnResponseStream( IAsyncResult ar )
    {
        try
        {
            if( ar.IsCompleted )
            {
                HttpWebRequest request = ar.AsyncState as HttpWebRequest;

                using( WebResponse response = request.EndGetResponse( ar ) as HttpWebResponse )
                {
                    // get the stream containing the response from the async call
                    using( Stream streamResult = response.GetResponseStream() )
                    {
                        using( StreamReader reader = new StreamReader( streamResult ) )
                        {
                            m_Response = reader.ReadToEnd();
                            reader.Close();

                            NotifySoapResponse();
                        }
                    }
                }
            }
        }
        catch( NotSupportedException nse )
        {
            Status = nse.Message;
        }
        catch( SecurityException se )
        {
            Status = se.Message;
        }
        catch( WebException we )
        {
            Debug.WriteLine( "OnResponseStream-WebException: " + we.Message);

            if( Nonce.Length == 0 )
            {
                HttpWebResponse response = (HttpWebResponse) we.Response;

                if( response.StatusCode == HttpStatusCode.Unauthorized )
                {
                    WebHeaderCollection coll = response.Headers;

                    String authHeader = we.Response.Headers["WWW-Authenticate"];
                    Debug.WriteLine( "Auth Header " + authHeader );

                    ComputeAuthAndRestartTheCall();

                    return;
                }
            }
            else
            {
                Nonce = "";
            }
        }
        catch( InvalidOperationException ie )
        {
            Status = ie.Message;
        }
    }

In ComputeAuthAndRestartTheCall();, you need to do your md5-auth and restart the call.

Points of Interest

This caused me a lot of trouble and I hope that somebody can learn from it. Here are the links to some interesting websites:

History

  • Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
I am living in germany and now living from programming for some Years. In my spare time I like sports as jogging, playing football (soccer) and basketball.

We must take care for our planet, because we and our family has no other. And everybody has to do something for it.

Comments and Discussions

 
GeneralMy vote of 5 Pin
maq_rohit28-Apr-14 11:46
professionalmaq_rohit28-Apr-14 11:46 
GeneralMy vote of 5 Pin
Volynsky Alex25-Apr-14 23:28
professionalVolynsky Alex25-Apr-14 23:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.