Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop credential caching on Windows.Web.Http.HttpClient?

I am having an issue where an app tries to access resources from the same server using different authentication methods, the two methods are:

  • Credentials (NTLM, Basic, etc)
  • OAuth (Bearer)

Setup HttpBaseProtocolFilter

The HttpBaseProtocolFilter is setup to:

  • disable Caching
  • disable automatic UI credential request popup

Code

HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.NoCache;
filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.MostRecent;
filter.AllowUI = false;

Adding Server Credential

If the resource needs credentials then I use:

filter.ServerCredential = new PasswordCredential(
                RequestUri.ToString(),
                UserName,
                Password);

HttpClient httpClient = new HttpClient(filter);

Adding OAuth Token

If the resource needs a Bearer token I use:

HttpClient httpClient = new HttpClient(filter);
httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("Bearer", token);

The ServerCredential are null

filter.ServerCredential = null

Getting response from server

using(httpClient)
{
   using(HttpRequestMessage requestMessage = new HttpRequestMessage(new HttpMethod(method), RequestUri))
   {
       using(HttpResponseMessage response = await httpClient.SendRequestAsync(requestMessage))
       {
           // Do something with response
       }
   }
}

The issue

If the HttpClient request returns a 200 (OK) using ServerCredential, then every following Bearer request also returns 200 (OK) even if the Bearer token is invalid and filter.ServerCredential is null.

It looks as if the filter.ServerCredential is cached and all subsequent calls are authenticated with the cached credentials.

I have to restart the app if I want to do a Bearer authentication.

How can I remove, disable or clear the ServerCredential of the Windows.Web.Http.HttpClient?


Things I've tried:

Deleting all cookies

var cookieManager = filter.CookieManager;
HttpCookieCollection myCookieJar = cookieManager.GetCookies(RequestUri);
foreach (HttpCookie cookie in myCookieJar)
{
    cookieManager.DeleteCookie(cookie);
}

The myCookieJar is empty.

Something with PasswordCredentialPropertyStore

Windows.Security.Credentials.PasswordCredentialPropertyStore credentialPropertyStore = new Windows.Security.Credentials.PasswordCredentialPropertyStore();

The credentialPropertyStore is empty.

AND

PasswordCredentialPropertyStore's method Clear is reserved for internal use and is not intended to be used in your code.

Any ideas?

like image 233
Barnstokkr Avatar asked Jun 09 '15 11:06

Barnstokkr


People also ask

How do I disable credential caching?

You can find it in Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Local Policies -> Security Options. You can set any value from 0 to 50 . If you set 0, this will prevent Windows from caching user credentials.

How do I pass Httpclient credentials?

You can set the required credentials to the CredentialsProvider object using the setCredentials() method. AuthScope object − Authentication scope specifying the details like hostname, port number, and authentication scheme name. Credentials object − Specifying the credentials (username, password).

Where are Windows cached credentials stored?

These credentials are stored on the hard disk drive and protected by using the Data Protection Application Programming Interface (DPAPI). Any program running as that user will be able to access credentials in this store.


2 Answers

This issue has now been resolved and the fix is included in the //build 2016 version of the SDK. There are two parts to this fix:

  1. In Windows build 10586 onwards, new credentials can overwrite older cached values in the same app. So, if you were using an instance of HttpClient c1 with (userA, paswordA), and then created a new client instance c2 with (userB, passwdB) in the same app: this should work. The new credentials overwrite the old cached ones (this would not work in earlier versions).

  2. However, #1 is still not sufficient to let you clear the original cached credentials - you can only overwrite them. To support clearing of cached credentials, we have now added a method to HttpBaseProtocolFilter - HttpBaseProtocolFilter.ClearAuthenticationCache() which clears all cached credential information. You can call this when you want to clear the credentials and/or client certificates from past instances of HttpClient in your app. The documentation for this method will soon be available here

Thanks Sidharth

[Windows Networking team]

like image 54
Sidharth Nabar Avatar answered Nov 12 '22 09:11

Sidharth Nabar


Just append

uwp_bugs_never_got_fixed={something never repeat}

in your request URL query parameters.

like image 1
Vangelis Avatar answered Nov 12 '22 08:11

Vangelis