ios - NSURLSession GET 请求仅通过 HTTPS 以 403 失败 - 代理时除外
问题描述
我正在对收到对某些 NSURLSession GET 请求的 403 响应的应用程序进行故障排除。该请求使用自定义标头来携带身份验证令牌。
问题是当我使用Proxyman查看请求时,每次都成功。包含 auth 标头的原始请求也通过 Postman 和 curl 成功。只有通过非代理应用程序才会失败。
源代码本身建议应将 403 视为“用户凭据失败”,并且服务器日志暗示部分凭据集可能包含在非代理请求中(存在用户名),而它们在代理一个。
我已经看到建议应在禁用 cookie 和凭证存储的情况下使用临时会话配置,但到目前为止,配置的任何变化都没有产生任何影响。
这是会话设置代码:
let sessionConfig = URLSessionConfiguration.ephemeral;
sessionConfig.timeoutIntervalForRequest = TimeInterval(timeout);
sessionConfig.urlCache = nil;
sessionConfig.requestCachePolicy = NSURLRequest.CachePolicy.reloadRevalidatingCacheData;
sessionConfig.httpCookieStorage = .none
sessionConfig.httpCookieAcceptPolicy = .never
sessionConfig.httpShouldSetCookies = false
sessionConfig.urlCredentialStorage = .none
var headers: [AnyHashable: Any] = [AnyHashable: Any]();
if let token = UserPreferences.getToken()
{
headers[HeaderTypes.Token.description] = token;
}
if let apiKey = self.apiKey
{
headers[HeaderTypes.API.description] = apiKey;
}
sessionConfig.httpAdditionalHeaders = headers;
self.session = URLSession(configuration: sessionConfig);
}
还有什么我应该检查的吗?
自原始帖子以来,我们已经尝试/确定了以下内容:
- 来自 iOS 应用程序的大多数呼叫似乎都有效。只有那些到达特定终点的人才会失败。
- 对该端点的调用使用 NSURLSession 而不是 NSURLConnection。这是我们可以看到的主要区别。
- 我们已经使用 Curl 和 Postman 测试了对服务器的调用,提供了适当的身份验证令牌,无论使用 HTTP 还是 HTTPS,这些调用总是成功的。
- 使用 HTTP 时,从 iOS 应用程序对端点的调用成功。
- 使用 HTTPS 时,从 iOS 应用程序调用端点失败并显示 403。该应用以前的程序员将 403 解释为“凭据失败”</li>
- 当我们通过提供自己的 HTTPS 证书的代理运行应用程序时,iOS 应用程序对端点的调用使用 HTTPS 成功。
- 我们可以看到,当使用 HTTPS 时,应用程序中会提出身份验证挑战,从而有机会询问 HTTPS 证书的有效性。当我们捕捉到这个并批准有效性时,服务器仍然返回 403。
- 我们已经对服务器的调用运行了诊断程序,以检查它们是否通过了 Apple 的应用程序传输安全 (ATS) 要求并且它们都通过了。
- 我们为 ATS 尝试了多种不同的设置,但行为没有明显差异
- 我们尝试强制 TLS 版本向上/向下,在行为上没有明显差异
- 有一些轶事证据表明,即使使用令牌身份验证,NSURLSession 也可能将来自先前请求的 cookie 传递给服务器。绕过此问题的建议包括将会话配置为使用临时配置。这里没有任何变化。
- 服务器日志表明,每次服务器返回 403 时,它都会知道进行呼叫的特定用户,因为用户名已填充到日志中。成功的呼叫没有记录用户名。这可能证实了第 11 点的轶事证据,但尝试检测和删除 cookie 的使用是不成功的(即我们无法确定应用程序是否正在发送 cookie,并且代码设置为假设它是't)。
- 在所有调用中具体包含用户凭据(即用于登录的凭据)以及身份验证令牌对任何一种方式都没有影响。
我们目前的想法是 HTTPS 设置和应用程序在某些情况下可能滥用 cookie 的一些奇怪组合导致服务器禁止对端点的请求(我们无法直接访问服务器、其配置或代码) .
解决方案
推荐阅读
- flutter - 如何在 Firebase 中向地图添加数据
- c - linux机器上连接SQL Server的C程序结构
- c++ - std::list 是循环的吗?
- android - 如何检索当前 Firestore 用户的数据
- linux - 页面的分页如何在 unix 系统中工作?
- reactjs - useEffect 导致无限循环
- python - 使用一致的小时标记在 python 中绘制时间序列
- javascript - 迭代深度优先搜索以找到 JavaScript 中的最长路径?
- python - 如何使用python中的变量更新sqlite3中的查询?
- javascript - 下载在 React konva JS 视频中不起作用