【问题标题】:How to stop credential caching on Windows.Web.Http.HttpClient?如何停止 Windows.Web.Http.HttpClient 上的凭据缓存?
【发布时间】:2015-06-09 11:59:45
【问题描述】:

我遇到了一个问题,即应用尝试使用不同的身份验证方法从同一服务器访问资源,这两种方法是:

  • 凭据(NTLM、基本等)
  • OAuth(不记名)

设置 HttpBaseProtocolFilter

HttpBaseProtocolFilter 设置为:

  • 禁用缓存
  • 禁用自动 UI 凭据请求弹出窗口

代码

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 令牌

如果资源需要我使用的 Bearer 令牌:

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

ServerCredential 为空

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 请求使用 ServerCredential 返回 200(OK),那么即使 Bearer 令牌无效且 filter.ServerCredential 为空,随后的每个 Bearer 请求也会返回 200(OK)。

看起来好像 filter.ServerCredential 已缓存,并且所有后续调用都使用缓存的凭据进行身份验证。

如果我想进行Bearer 身份验证,我必须重新启动应用程序。

如何删除、禁用或清除 Windows.Web.Http.HttpClient 的ServerCredential


我尝试过的事情:

删除所有 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的方法清除is reserved for internal use and is not intended to be used in your code.

有什么想法吗?

【问题讨论】:

  • 在没有任何知识的情况下,我猜也许您可以在 using 块中使用 HttpClient 并关闭每个不同的请求。当然,作为一种解决方法。
  • 这实际上是我正在做的...... :(
  • 很奇怪,即使在离开 using 块之后仍然保留凭据。看起来它正在操作系统中的用户级别缓存
  • 如果是windows 8.1,请求完成后是否在控制面板的凭据管理器中找到密码?您可以尝试清除此请求的 Uri 的密码凭据,try { var credentials = _vault.FindAllByResource(PasswordVault); foreach(var passwordCredential in credentials) { _vault.Remove(passwordCredential); } } catch { // ignored }
  • 您是否尝试过使用System.Net.Http

标签: c# windows-phone-8.1 windows-8.1 httpclient win-universal-app


【解决方案1】:

感谢您报告此问题。这是位于操作系统中 Windows.Web.Http.HttpClient API 下方的低级 WinINet HTTP 堆栈中的已知行为。一旦 HTTP 请求成功,凭据就会缓存在该应用程序的进程内存中。因此,即使您创建了一个新的 HttpClient 实例并将不同的凭据设置到 HttpBaseProtocolFilter 中,只要它们在服务器端继续有效,就会应用相同的(原始)凭据并使用它们。 (如果缓存的凭据在服务器端不再有效,它们将被新提供的凭据覆盖。)

我们已注意到此问题,并正在努力通过允许清除缓存的凭据来解决此问题。不幸的是,目前唯一的解决方法是让用户重新启动应用程序,这将清除应用程序的进程内存。这将允许首先使用不同的凭据。但是,只要该凭据在服务器上有效,该凭据也将“保留”到应用程序进程的其余部分。

谢谢,

西达斯·纳巴尔 [Windows 网络团队]

【讨论】:

  • Sidharth:感谢您的回答。这对我们来说是一个大问题。在 Windows 8.1 中使用 System.Web HttpClient 时不会发生这种情况,但由于您现在在 UWP 中使用 WinInet,因此在 UWP 应用程序上下文中运行的现有代码(更重要的是 SDK)可能存在重大安全问题,因为退出不再有效。这应该是一个高度优先的问题。
  • 嗨@dotMorten,我们现在已经修复了这个问题,修复包含在 Insider build 10586 (blogs.windows.com/windowsexperience/2015/11/05/…) 中。请尝试在此版本上编译您的应用程序。另外,对术语进行了轻微的更正-我认为您的意思是“System.Net.Http.HttpClient”而不是“System.Web HttpClient”,对吗?谢谢
  • 谢谢@sidharth。但是我仍然可以重现该问题。我会向你发送一封电子邮件,并附上一份复制品。
【解决方案2】:

此问题现已解决,此修复程序包含在 SDK 的 //build 2016 版本中。此修复分为两部分:

  1. 在 Windows 内部版本 10586 及更高版本中,新凭据可以覆盖同一应用程序中较旧的缓存值。因此,如果您使用带有(userA,passwordA)的 HttpClient c1 实例,然后在同一个应用程序中使用(userB,passwdB)创建了一个新的客户端实例 c2:这应该可以工作。新凭据会覆盖旧的缓存凭据(这在早期版本中不起作用)。

  2. 但是,#1 仍然不足以让您清除原始缓存凭据 - 您只能覆盖它们。为了支持清除缓存的凭据,我们现在向 HttpBaseProtocolFilter 添加了一个方法 - HttpBaseProtocolFilter.ClearAuthenticationCache(),它会清除所有缓存的凭据信息。当您想从应用程序中过去的 HttpClient 实例中清除凭据和/或客户端证书时,您可以调用它。此方法的文档很快就会提供here

谢谢 西哈特

[Windows 网络团队]

【讨论】:

  • 谢谢西德哈斯。我正在开发一个运行 om 10586 的 UWP 应用程序,但我没有看到任何可用的 HttpBaseProtocolFilter.ClearAuthenticationCache() ???我正在运行带有更新 2 的 VS 2015,并且已安装“工具 (1.3.1) 和 Windows 10 SDK (10.0.10586)”。我错过了什么?
  • @JasperHedegaardBojsen - 最近才添加了 ClearAuthenticationCache API(10586 是 2015 年 11 月的版本)。请通过 Windows Insider 程序使用 Windows 周年纪念 SDK 预览版(版本 14295) - insider.windows.com
【解决方案3】:

只是追加

uwp_bugs_never_got_fixed={something never repeat}

在您的请求 URL 查询参数中。

【讨论】:

  • 我已经在 URL 查询参数中添加了一个 Nonce,但它不能解决问题
【解决方案4】:

对于面临这个问题的人;

我在 UWP Phone 应用程序上遇到了相同的基本凭据问题;一旦用户成功通过身份验证一次,它就会缓存这些凭据。即使关闭应用程序,即使重新启动手机。老实说,我怀疑服务器端存在错误,但有一个类似的应用程序可以在同一台服务器上按预期工作。

我发现添加:

filter.CookieUsageBehavior = HttpCookieUsageBehavior.NoCookies

解决了我的问题。当输入正确的凭据时一切都很好,当使用错误的凭据重试身份验证失败时。正是它应该做的!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 2014-11-04
    • 2017-11-24
    • 2018-06-15
    • 2016-03-13
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多