Подтвердить что ты не робот

Как остановить кэширование учетных данных в Windows.Web.Http.HttpClient?

У меня возникла проблема, когда приложение пытается получить доступ к ресурсам с того же сервера с использованием разных методов проверки подлинности, два метода:

  • Учетные данные (NTLM, Basic и т.д.)
  • OAuth (Bearer)

Настройка HttpBaseProtocolFilter

HttpBaseProtocolFilter настроен на:

  • отключить кеширование
  • отключить автоматический запрос учетных данных пользовательского интерфейса

код

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

Добавление учетных данных сервера

Если ресурс нуждается в учетных данных, я использую:

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

HttpClient httpClient = new HttpClient(filter);

Добавление токена OAuth

Если ресурсу нужен токен-носитель, я использую:

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

ServerCredential имеют значение null

filter.ServerCredential = null

Получение ответа от сервера

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

Проблема

Если запрос HttpClient возвращает 200 (OK) с помощью ServerCredential, то каждый следующий запрос Bearer также возвращает 200 (OK), даже если токен Bearer недействителен, а filter.ServerCredential - null.

Похоже, что filter.ServerCredential кэшируется, и все последующие вызовы аутентифицируются с кэшированными учетными данными.

Мне нужно перезапустить приложение, если я хочу выполнить проверку Bearer.

Как удалить, отключить или очистить ServerCredential для Windows.Web.Http.HttpClient?


Вещи, которые я пробовал:

Удаление всех файлов cookie

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

myCookieJar пуст.

Что-то с PasswordCredentialPropertyStore

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

credentialPropertyStore пуст.

и

PasswordCredentialPropertyStore метод Clear зарезервирован для внутреннего использования и не предназначен для использования в вашем коде.

Любые идеи?

4b9b3361

Ответ 1

Теперь эта проблема устранена, и исправление включено в версию SDK//build 2016. В этом исправлении есть две части:

  • В Windows 10586 новые учетные данные могут перезаписывать старые кешированные значения в одном приложении. Итак, если вы использовали экземпляр HttpClient c1 с (userA, paswordA), а затем создали новый экземпляр клиента c2 с (userB, passwdB) в том же приложении: это должно работать. Новые учетные данные перезаписывают старые кешированные (это не работает в более ранних версиях).

  • Однако, # 1 все еще недостаточно, чтобы вы могли очистить исходные кэшированные учетные данные - их можно только перезаписать. Чтобы поддерживать очистку кэшированных учетных данных, мы теперь добавили метод HttpBaseProtocolFilter - HttpBaseProtocolFilter.ClearAuthenticationCache(), который очищает всю информацию о кэшировании учетных данных. Вы можете вызвать это, когда хотите очистить учетные данные и/или клиентские сертификаты из прошлых экземпляров HttpClient в своем приложении. Документация для этого метода скоро будет доступна здесь

Спасибо Sidharth

[Команда Windows Networking]

Ответ 2

Спасибо за сообщение об этой проблеме. Это известное поведение в низкоуровневом стеке WinINet HTTP, который находится под API Windows.Web.Http.HttpClient в операционной системе. Как только HTTP-запрос завершается успешно, учетные данные кэшируются в памяти процесса для этого приложения. Следовательно, даже если вы создаете новый экземпляр HttpClient и устанавливаете разные учетные данные в HttpBaseProtocolFilter, применяются те же (оригинальные) учетные данные и будут использоваться до тех пор, пока они будут оставаться действительными на стороне сервера. (Если кешированные учетные данные перестают быть действительными на стороне сервера, они будут перезаписаны вновь предоставленными.)

Мы знаем об этой проблеме и работаем над ее исправлением, разрешая очистку кэшированных учетных данных. К сожалению, единственным обходным решением в настоящее время является перезапуск приложения, которое очистит память процесса для приложения. Это позволит использовать разные учетные данные вначале. Тем не менее, этот учет также будет "придерживаться" для остальной части процесса приложения, если он действителен на сервере.

Спасибо,

Сидхарт Набар [Команда Windows Networking]

Ответ 3

Просто добавьте

uwp_bugs_never_got_fixed={something never repeat}

в параметрах запроса URL запроса.

Ответ 4

Для тех, кто сталкивается с этой проблемой;

У меня была такая же проблема с базовыми учетными данными в приложении UWP Phone; Как только пользователь получил аутентификацию успешно один раз, он кэшировал эти учетные данные. Даже при закрытии приложения даже при перезапуске телефона. Я честно заподозрил ошибку на сервере или около того, но было похожее приложение, которое работало как ожидалось против того же сервера.

Я обнаружил, что добавление:

filter.CookieUsageBehavior = HttpCookieUsageBehavior.NoCookies

решил мою проблему. При вводе правильных учетных данных все было в порядке, когда попытка повторной проверки подлинности с ложными учетными данными не удалась. Точно так, как это предполагается!