2

We have a 3rd party web service that we consume from our web application. I've created a windows service that call this web service for all our customer, each of them with their own credentials.

The web service is using basic authentication.

When cycling through the credentials, it always uses the first authenticated credential.

Example code below:

private void testConnection(string username, string password)
{
    _url = "https://somewebservice.com.au/transport/SomeService";

    using (var someWebService = new someWebService {Url = _url})
    {
        var netCredential = new NetworkCredential(username, password);
        var credential = new CredentialCache
        {
            {new Uri(someWebService.Url), "Basic", new NetworkCredential(username, password)}
        };

        someWebService.Credentials = credential;
        someWebService.PreAuthenticate = true;
        someWebService.Timeout = 1200000;

        try
        {
            var result = someWebService.testConnection();
            textBoxMsg.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), result);
        }
        catch (SoapException soapex)
        {
            textBoxMsg.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), "SOAP Error: " + soapex.Message + "\r\n");
        }
        catch (WebException webex)
        {
            textBoxMsg.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), "Web Error: " + webex.Message + "\r\n");
        }
        catch (Exception ex)
        {
            textBoxMsg.Invoke(new UpdateTextBoxDelegate(UpdateTextBox), "Error: " + ex.Message + "\r\n");
        }
        finally
        {
            credential.Remove(new Uri(someWebService.Url), "Basic");
        }
    }
}

private void buttonTest2_Click(object sender, EventArgs e)
{
    ThreadStart start = () => testConnection("user1", "123");
    new Thread(start).Start();
}

private void buttonTest3_Click(object sender, EventArgs e)
{
    ThreadStart start = () => testConnection("user2", "1234");
    new Thread(start).Start();
}

if "user1" is authenticated first, second call to testConnection will always use "user1" credentials.

I've tried setting HttpWebRequest KeepAlive to false so connection is not re-used. TCP monitoring show the connection getting killed after setting it to false. This did not solve the issue.

If I close down the application and restart, and run testConnection for "user2", it gives the correct result.

Seems like the credentials are cached in the process. The only way to get rid of it is to exit the process.

This present some challenges when I have to cycle through about 1000 credentials.

Is there a way to clear the credential cache in process? If that is what's happening. See this link How to stop credential caching on Windows.Web.Http.HttpClient?

Options that I've explored and protoyped

  • Self hosted WCF accessing the web service. Another process that start and stop the WCF service for every credential
  • WCF service hosted in Windows Services - Another process that start and stop the windows service for every credential
  • Wait more than 10 mins for server side credential to expire. Not viable too slow.

My problem with the aboves are they have to be sequential, so to cycle through 1000 of them will take a while. Each credential will be around 20-30 secs.

Community
  • 1
  • 1
Bruce Chua
  • 31
  • 3

2 Answers2

0

Try using CredentialCache.Remove() method after your last catch block. https://msdn.microsoft.com/en-us/library/4zaz5c95(v=vs.110).aspx

This will remove it from cache.

Gandhali Samant
  • 877
  • 4
  • 10
0

Maybe this is a bit old question, but you PreAuthenticate should be false for HttpClient not to cache the credentials.

marcofo88
  • 375
  • 2
  • 10