如何在Windows.Web.Http.HttpClient上停止凭据缓存?
我遇到一个问题,即应用程序尝试使用不同的身份validation方法从同一服务器访问资源,这两种方法是:
- 证书(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
为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
请求使用ServerCredential
返回200(OK),则即使Bearer
令牌无效且filter.ServerCredential
为null,每个后续Bearer
请求也返回200(OK)。
看起来好像缓存了filter.ServerCredential
,并且所有后续调用都使用缓存的凭据进行身份validation。
如果我想进行Bearer
身份validation,我必须重新启动应用程序。
如何删除,禁用或清除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
的方法Clear 保留供内部使用,不应在您的代码中使用。
有任何想法吗?
此问题现已解决,修复程序包含在// build 2016版本的SDK中。 这个修复有两个部分:
-
在Windows Build 10586之后,新凭据可以覆盖同一应用程序中较旧的缓存值。 因此,如果您使用HttpClient c1的实例(userA,paswordA),然后在同一个应用程序中创建一个新的客户端实例c2(userB,passwdB):这应该可行。 新凭据会覆盖旧的高速缓存(这在早期版本中不起作用)。
-
但是,#1仍然不足以让您清除原始缓存凭据 – 您只能覆盖它们。 为了支持清除缓存凭据,我们现在为HttpBaseProtocolFilter添加了一个方法 – HttpBaseProtocolFilter.ClearAuthenticationCache() ,它清除所有缓存的凭据信息。 如果要从应用程序中的过去HttpClient实例中清除凭据和/或客户端证书,可以调用此方法。 此方法的文档很快就会在此处提供
谢谢Sidharth
[Windows网络团队]
感谢您报告此问题。 这是位于操作系统中Windows.Web.Http.HttpClient API下的低级WinINet HTTP堆栈中的已知行为。 HTTP请求成功后,凭据将缓存在该应用程序的进程内存中。 因此,即使您创建了一个新的HttpClient实例并将不同的凭据设置到HttpBaseProtocolFilter中,也会使用相同的(原始)凭证,只要它们在服务器端继续有效即可使用。 (如果缓存的凭据在服务器端停止有效,则它们将被新提供的凭据覆盖。)
我们知道这个问题,并正在通过允许清除缓存凭据来纠正它。 不幸的是,目前唯一的解决方法是让用户重启应用程序,这将清除应用程序的进程内存。 这将允许首先使用不同的凭证。 但是,只要在服务器上有效,该凭证也将“粘贴”应用程序进程的其余部分。
谢谢,
Sidharth Nabar [Windows网络团队]
只需追加
uwp_bugs_never_got_fixed={something never repeat}
在您的请求URL查询参数。
对于任何面临这个问题的人;
我在UWP手机应用程序上遇到了与基本凭证相同的问题; 一旦用户成功通过身份validation,就会缓存这些凭据。 即使在关闭应用程序时,即使重新启动手机也是如此。 老实说,我怀疑服务器端有一个错误,但是有一个类似的应用程序可以按照预期在同一台服务器上运行。
我发现添加:
filter.CookieUsageBehavior = HttpCookieUsageBehavior.NoCookies
解决了我的问题。 输入正确的凭据时,一切都很好,当使用虚假凭据进行重试时,身份validation失败。 完全按照它应该做的!