locked
HttpClient with HttpBaseProtocolFilter.ServerCredential will resend the PasswordCredential in different http request

    Question

  • Hi,

      We use Windows.Web.Http.HttpClient to connect several URLS={U1,U2,U3}. In U1, we need ntlm auth, so the HttpClient is set with HttpBaseProtocolFilter.ServerCredential. In U2 and U3, we don't need the ntlm auth. The behavior is fine, when the U1's username and password are correct. However, if the username and password are incorrect, the HttpClient will retry the ntlm auth in next U2 and U3 with new HttpClient instance object. Following is the code:

    string[] uri = {"U1", "U2", "U3"};
    string[] msg = {"msg1", "msg2", "msg3"};
    
    for( int i = 0; i < 3; i++ )
    {
                HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
                filter.AllowUI = false;
                if( uri[i] == "U1" )
                {         
                filter.ServerCredential = new Windows.Security.Credentials.PasswordCredential(uri[i], username, password);
                }
                filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.Default;
                filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.NoCache;
                HttpClient client = new HttpClient(filter);
                var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(uri[i]));
                HttpStringContent content = new HttpStringContent(msg[i], Windows.Storage.Streams.UnicodeEncoding.Utf8 , "application/json");
                httpRequestMessage.Content = content;
    
                var response = await httpClient.SendRequestAsync(httpRequestMessage);
                string respStr = await resp.Content.ReadAsStringAsync();
    }

    Thanks.

    Tuesday, July 15, 2014 2:59 AM

All replies

  • Hi,

    maybe there is a copy paste error, but you use the variables "httpClient" and "resp" in the last two code rows. But you define variables "client" and "response". Are you sure that httpClient isn't something defined in the class?

    I'll try to reproduce it now...


    ---------------------------------- Robin Sedlaczek @ Microsoft Forums

    Tuesday, July 15, 2014 12:33 PM
  • Hm, I cannot reproduce it. Strange problem. Did you catch all exceptions? Maybe if you have a closer look at possible exceptions and their inner exceptions, there will be an hint for you.

    ---------------------------------- Robin Sedlaczek @ Microsoft Forums

    Tuesday, July 15, 2014 2:33 PM
  • does this fix the problem:
     if( uri[i] == "U1" )
                {         
                filter.ServerCredential = new Windows.Security.Credentials.PasswordCredential(uri[i], username, password);
                }
                else
                {
                filter.ServerCredential = null;
                {
    
    I added the bold part.

    Darin R.

    Tuesday, July 15, 2014 8:04 PM
  • Was my thought, too. But since there are new instances for the filter and the client, it seems to me, that setting the credentials to null would not help. But maybe...

    ---------------------------------- Robin Sedlaczek @ Microsoft Forums

    Wednesday, July 16, 2014 9:48 AM
  • I know you re- create the object each time, but I was just wondering if an underlying network cache stored the credentials somehow. 

    I read that if you make an HTTP call through a proxy (for example), the system can then use the same authentication for later socket calls without having the sockets themselves provide any authentication. 

    Might be the same thing.  I was hoping that setting the security to null would store the null creds instead of using the prev stored item.


    Darin R.

    Wednesday, July 16, 2014 5:00 PM
  • Hi Robin,

      Yes it is a typo. From our observation, the underlining implementation of the httpclient contains some cache mechanism to send the ntlm auth package in some condition. We will try set the ServerCredential to null.

    Thursday, July 17, 2014 6:07 AM
  • Hi Darin,

    We try to set the ServerCredential to null, while it doesn't work too. The ntlm auth request is also sent.

    Thursday, July 17, 2014 6:48 AM
  • Maybe you can try to set the credentials to null directly after you used it and got the response and BEFORE the for-loop continues. I mean at the last line of the for-statement.

    ---------------------------------- Robin Sedlaczek @ Microsoft Forums

    Thursday, July 17, 2014 11:48 AM
  • It doesn't work too. Can anyone in MS who dev the httpclient module tell me why?
    Friday, July 18, 2014 5:54 AM
  • Can you capture a network trace of this? 

    I'd be curious to know if each request was somehow incorrectly using the same TCP socket, and if the authentication headers were actually going out with each request.


    Darin R.

    Friday, July 18, 2014 3:24 PM
  • Hi

    i upload the package to below url https://onedrive.live.com/redir?resid=37605595D960067C%21105

    we set filter.ServerCredential = null and hope client send normal package to server, but client always send NTLM negotiate package.


    Wednesday, July 30, 2014 8:53 AM
  • this is right package capture .https://onedrive.live.com/redir?resid=37605595D960067C%211812

    most of time, the client send NTLM package. we need to know how to HTTPClient not with NTLM authentication.

    Wednesday, July 30, 2014 9:12 AM
  • I'm checking into this.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, July 31, 2014 2:38 PM
    Moderator
  • I cannot reproduce this issue using your code against a localhost machine.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, July 31, 2014 3:17 PM
    Moderator