Why my Http client making 2 requests when I specify credentials?

Viewed 6721

I created RESTful webservice (WCF) where I check credentials on each request. One of my clients is Android app and everything seems to be great on server side. I get request and if it's got proper header - I process it, etc..

Now I created client app that uses this service. This is how I do GET:

// Create the web request  
            var request = WebRequest.Create(Context.ServiceURL + uri) as HttpWebRequest;

            if (request != null)
            {
                request.ContentType = "application/json";

                // Add authentication to request  
                request.Credentials = new NetworkCredential(Context.UserName, Context.Password);

                // Get response  
                using (var response = request.GetResponse() as HttpWebResponse)
                {
                    // Get the response stream  
                    if (response != null)
                    {
                        var reader = new StreamReader(response.GetResponseStream());

                        // Console application output
                        var s = reader.ReadToEnd();

                        var serializer = new JavaScriptSerializer();
                        var returnValue = (T)serializer.Deserialize(s, typeof(T));

                        return returnValue;
                    }
                }
            }

So, this code get's my resource and deserializes it. As you see - I'm passing credentials in my call.

Then when debugging on server-side I noticed that I get 2 requests every time - one without authentication header and then server sends back response and second request comes bach with credentials. I think it's bad for my server - I'd rather don't make any roundtrips. How should I change client so it doesn't happen? See screenshot of Fiddler

First BAD request

Second GOOD request

EDIT:

This is JAVA code I use from Android - it doesn't do double-call:

MyHttpResponse response = new MyHttpResponse();
        HttpClient client = mMyApplication.getHttpClient();

        try
        {
            HttpGet request = new HttpGet(serviceURL + url);
            request.setHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            request.addHeader("Authorization", "Basic " + Preferences.getAuthorizationTicket(mContext));

            ResponseHandler<String> handler = new BasicResponseHandler();
            response.Body = client.execute(request, handler);
            response.Code = HttpURLConnection.HTTP_OK;
            response.Message = "OK";
        }
        catch (HttpResponseException e)
        {
            response.Code = e.getStatusCode();
            response.Message = e.getMessage();

            LogData.InsertError(mContext, e);
        }
3 Answers

As an option you can use PreAuthenticate property of HttpClientHandler. This would require a couple of lines more

            var client = new HttpClient(new HttpClientHandler
            {
                Credentials = yourCredentials,
                PreAuthenticate = true
            });

With using this approach, only the first request is sent without credentials, but all the rest requests are OK.

Related