Click here to Skip to main content
Click here to Skip to main content

Trouble with HttpWebRequest Authorization

, 25 Apr 2014
Rate this:
Please Sign up or sign in to vote.
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.

    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)

Share

About the Author

KarstenK
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 Pinpremiummaq_rohit a.k.a asthanarht28-Apr-14 11:46 
GeneralMy vote of 5 PinpremiumVolynsky Alex25-Apr-14 23:28 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 25 Apr 2014
Article Copyright 2014 by KarstenK
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid