首页 > 解决方案 > 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);
    }

还有什么我应该检查的吗?

自原始帖子以来,我们已经尝试/确定了以下内容:

  1. 来自 iOS 应用程序的大多数呼叫似乎都有效。只有那些到达特定终点的人才会失败。
  2. 对该端点的调用使用 NSURLSession 而不是 NSURLConnection。这是我们可以看到的主要区别。
  3. 我们已经使用 Curl 和 Postman 测试了对服务器的调用,提供了适当的身份验证令牌,无论使用 HTTP 还是 HTTPS,这些调用总是成功的。
  4. 使用 HTTP 时,从 iOS 应用程序对端点的调用成功。
  5. 使用 HTTPS 时,从 iOS 应用程序调用端点失败并显示 403。该应用以前的程序员将 403 解释为“凭据失败”</li>
  6. 当我们通过提供自己的 HTTPS 证书的代理运行应用程序时,iOS 应用程序对端点的调用使用 HTTPS 成功。
  7. 我们可以看到,当使用 HTTPS 时,应用程序中会提出身份验证挑战,从而有机会询问 HTTPS 证书的有效性。当我们捕捉到这个并批准有效性时,服务器仍然返回 403。
  8. 我们已经对服务器的调用运行了诊断程序,以检查它们是否通过了 Apple 的应用程序传输安全 (ATS) 要求并且它们都通过了。
  9. 我们为 ATS 尝试了多种不同的设置,但行为没有明显差异
  10. 我们尝试强制 TLS 版本向上/向下,在行为上没有明显差异
  11. 有一些轶事证据表明,即使使用令牌身份验证,NSURLSession 也可能将来自先前请求的 cookie 传递给服务器。绕过此问题的建议包括将会话配置为使用临时配置。这里没有任何变化。
  12. 服务器日志表明,每次服务器返回 403 时,它都会知道进行呼叫的特定用户,因为用户名已填充到日志中。成功的呼叫没有记录用户名。这可能证实了第 11 点的轶事证据,但尝试检测和删除 cookie 的使用是不成功的(即我们无法确定应用程序是否正在发送 cookie,并且代码设置为假设它是't)。
  13. 在所有调用中具体包含用户凭据(即用于登录的凭据)以及身份验证令牌对任何一种方式都没有影响。

我们目前的想法是 HTTPS 设置和应用程序在某些情况下可能滥用 cookie 的一些奇怪组合导致服务器禁止对端点的请求(我们无法直接访问服务器、其配置或代码) .

标签: iosswiftnsurlsession

解决方案


推荐阅读