首次成功调用 REST 后,未验证 HttpClient 上的凭据
Posted
技术标签:
【中文标题】首次成功调用 REST 后,未验证 HttpClient 上的凭据【英文标题】:Credentials on HttpClient is not validated after first successful REST call 【发布时间】:2013-10-15 08:46:28 【问题描述】:我正在创建一个用户使用用户名、密码和域登录的应用程序。我想尽可能多地在 Windows 平台上重复使用它,所以我在可移植类库中使用 nuget 包 Microsoft HTTP 客户端库。
这是我使用 HttpClientHandler 创建 HttpClient 然后调用 GetAsync 的方法。
HttpClientHandler handler = new HttpClientHandler();
ICredentials myCredentials = new NetworkCredential("Username", "Password", "Domain");
handler.Credentials = myCredentials;
HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.BaseAddress = new Uri("https://....");
HttpResponseMessage response = await client.GetAsync("...");
这似乎工作正常。凭据在请求中发送,并且只允许注册用户获取数据。
在我的应用程序中,用户还可以选择退出,然后使用其他用户名、密码或域重新登录。这就是问题所在。 如果我曾经使用一些有效的凭据调用 client.GetAsync,HttpClient 似乎会记住旧的用户凭据,尽管我每次都创建一个新的 HttpClient 实例并为新用户设置正确的凭据。
所以我的问题是,HttpClient 是保持网络通道打开还是存在一些我不知道的会话问题?
--- 更新 #1 ---
如果我在 GetAsync(...) 中使 URL 唯一,例如我可以在请求中传递一些随机参数,服务器将验证凭据,只有授权用户才能访问资源。这不是一个很好的解决方案,所以我做了更多的研究。
我看起来服务器正在发送一个名为 Persistent-Auth: true 的响应标头。这告诉客户端下一个请求不需要授权标头。我猜这就是为什么下次我尝试为同一资源调用 GetAsync 时不发送凭据的原因。令人惊讶的是,我还在 Fiddler 中注意到,对于对该资源的第二次请求,客户端根本没有发送任何 HTTP 请求。
一个有趣的事情是,如果我在浏览器中尝试相同的方法,授权具有相同的行为,因此它只包含在第一个请求中。对于对同一资源的第二次请求,我可以在 Fiddler 中看到 HTTP 请求正在按照您的预期发送。
所以总结一下。我想我遇到了两个问题。首先,是否可以更改此 Persistent-Auth 行为,以便在服务器响应中将其设置为 false。其次,为什么我的应用程序在我第二次请求相同的资源时根本没有发送任何请求。
【问题讨论】:
您确定client
对象已被处置吗?
您在哪些平台上看到了这种行为?例如,在 Windows Phone 上,操作系统通常会缓存结果并在您请求相同的 URL 时将其返回给您。
@RameezAhmedSayad:我尝试在请求后在客户端和处理程序上调用 Dispose(),但它似乎没有改变任何东西。
@DanielPlaisted:它在 Windows Phone 上。你知道我是否可以尝试禁用该行为?
@NicolajHedeagerLarsen:由于这是缓存问题,也许您可以尝试将标头添加到响应中,不确定***.com/questions/49547/…
【参考方案1】:
根据这个问题的答案: How to stop credential caching on Windows.Web.Http.HttpClient?
它应该适用于 Windows build 10586 及更高版本。 要手动清除所有缓存的凭据,我们还可以调用 HttpBaseProtocolFilter.ClearAuthenticationCache() 方法清除所有缓存的凭据信息。可以在此处找到此方法的文档:https://docs.microsoft.com/en-us/uwp/api/Windows.Web.Http.Filters.HttpBaseProtocolFilter
【讨论】:
以上是关于首次成功调用 REST 后,未验证 HttpClient 上的凭据的主要内容,如果未能解决你的问题,请参考以下文章
检测用户首次使用 Django Rest Framework 进行身份验证
Django Rest Framework JWT 未提供身份验证凭据
使用动态链接首次下载后更新应用程序时未调用 openURL 方法