指定凭据时,为什么我的Http客户端发出2个请求?

| 我创建了RESTful Web服务(WCF),在其中检查每个请求的凭据。我的客户之一是Android应用,在服务器端一切似乎都很棒。我收到请求,并且如果有正确的标头,则进行处理,依此类推。 现在,我创建了使用此服务的客户端应用程序。这就是我的方法:
// 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;
                    }
                }
            }
因此,此代码获取了我的资源并反序列化了它。如您所见-我正在通话中传递凭据。 然后在服务器端进行调试时,我注意到每次都会收到2个请求-一个不带身份验证标头,然后服务器发送回响应,第二个请求带有凭据。我认为这对我的服务器不利-我宁愿不进行任何往返。我应该如何更改客户端,使其不会发生?查看Fiddler的屏幕截图 编辑: 这是我在Android上使用的JAVA代码-它不会进行重复通话:
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);
        }
    
已邀请:
        初始请求永远不会指定身份验证的基本标头。此外,由于已指定领域,因此您必须从服务器获取该领域。因此,您必须问一次:“嘿,我需要这个东西”,服务器转到“您是谁?”的回答范围是“安全区域”。(因为领域在这里表示某些含义)仅因为您在此处添加了它:
request.Credentials = new NetworkCredential(Context.UserName, Context.Password);
并不意味着它肯定会每次都附加到请求中。 然后,您用用户名/密码进行响应(在这种情况下,您正在执行BASIC,因此它的base64编码为name:password),服务器将其解码并说“好,您很清楚,这里\是您的数据\“。 这将定期发生,您对此无能为力。我建议您也打开HTTPS,因为身份验证是通过Internet以纯文本方式进行的。 (实际上,您显示的内容似乎是通过Intranet进行的,但是如果您通过Internet进行访问,则将其设置为https)。 以下是指向Wikipedia的链接,该链接可能会进一步帮助您:http://en.wikipedia.org/wiki/Basic_access_authentication     
        好,我知道了。我手动设置HttpHeader而不是使用request.Credentials
request.Headers.Add(HttpRequestHeader.Authorization, \"Basic \" + Convert.ToBase64String(Encoding.UTF8.GetBytes(Context.UserName + \":\" + Context.Password)));
现在,我仅看到预期的单个请求。     
        作为一种选择,您可以使用HttpClientHandler的PreAuthenticate属性。这将需要几行
            var client = new HttpClient(new HttpClientHandler
            {
                Credentials = yourCredentials,
                PreAuthenticate = true
            });
使用这种方法,仅发送第一个请求而没有凭据,但是其余所有请求都可以。     

要回复问题请先登录注册