使用自签名证书在 iOS 9 中发出 HTTPS 请求 [关闭]

2023-11-20

我想使用自签名证书向自定义服务器发出 HTTPS 请求。我正在使用 NSURLConnection 类并处理身份验证质询,但总是在控制台中收到错误消息:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

然后方法“connection:didFailWithError:”被调用并出现以下错误:

Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x150094100>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=<CFArray 0x1500ddd90 [0x19f6dab68]>{type = immutable, count = 1, values = (
    0 : <cert(0x14e6fb370) s: (server certificate name) i: (custom CA name)>
)}, NSUnderlyingError=0x1504ae170 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://217.92.80.156:9090/(method name and parameters), NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x1500ddd90 [0x19f6dab68]>{type = immutable, count = 1, values = (
    0 : <cert(0x14e6fb370) s: (server certificate name) i: (custom CA name)>
)}, _kCFStreamPropertySSLClientCertificateState=2, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x150094100>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFStreamPropertySSLClientCertificates=<CFArray 0x14e5ee8e0 [0x19f6dab68]>{type = mutable-small, count = 2, values = (
    0 : <SecIdentityRef: 0x15012cd40>
    1 : <cert(0x15014aa70) s: (client certificate name) i: (custom CA name)>
)}, _kCFStreamErrorDomainKey=3, NSErrorFailingURLKey=https://217.92.80.156:9090/(method name and parameters), _kCFStreamErrorCodeKey=-9802}}, NSErrorClientCertificateChainKey=<CFArray 0x14e5ee8e0 [0x19f6dab68]>{type = mutable-small, count = 2, values = (
    0 : <SecIdentityRef: 0x15012cd40>
    1 : <cert(0x15014aa70) s: (client certificate name) i: (custom CA name)>
)}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://217.92.80.156:9090/(method name and parameters), NSErrorFailingURLStringKey=https://217.92.80.156:9090/(method name and parameters), NSErrorClientCertificateStateKey=2}

应用程序收到两个身份验证质询(NSURLAuthenticationMethodClientCertificate 和 NSURLAuthenticationMethodServerTrust)并按以下方式处理它们:

- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if(challenge.proposedCredential && !challenge.error)
    {
        [challenge.sender useCredential:challenge.proposedCredential forAuthenticationChallenge:challenge];

        return;
    }

    NSString *strAuthenticationMethod = challenge.protectionSpace.authenticationMethod;
    NSLog(@"authentication method: %@", strAuthenticationMethod);

    NSURLCredential *credential = nil;
    if([strAuthenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])
    {
        // get identity and certificate from p.12
        NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]];

        NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"password" forKey:(__bridge id)kSecImportExportPassphrase];
        CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
        OSStatus securityError = SecPKCS12Import((__bridge CFDataRef)PKCS12Data,(__bridge CFDictionaryRef)optionsDictionary, &items);

        SecIdentityRef identity = NULL;
        SecCertificateRef certificate = NULL;
        if(securityError == errSecSuccess)
        { 
            CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
            identity = (SecIdentityRef)CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);

            CFArrayRef array = (CFArrayRef)CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemCertChain);
            certificate = (SecCertificateRef)CFArrayGetValueAtIndex(array, 0);
        }

        credential = [NSURLCredential credentialWithIdentity:identity certificates:[NSArray arrayWithObject:(__bridge id)(certificate)] persistence:NSURLCredentialPersistenceNone];

        CFRelease(items);
    }
    else if([strAuthenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {       
        int trustCertificateCount = (int)SecTrustGetCertificateCount(challenge.protectionSpace.serverTrust);
        NSMutableArray *trustCertificates = [[NSMutableArray alloc] initWithCapacity:trustCertificateCount];
        for(int i = 0; i < trustCertificateCount; i ++)
        {
            SecCertificateRef trustCertificate =  SecTrustGetCertificateAtIndex(challenge.protectionSpace.serverTrust, i);
            [trustCertificates addObject:(__bridge id) trustCertificate];
        }            

        SecPolicyRef policyRef = NULL;
        policyRef = SecPolicyCreateSSL(YES, (__bridge CFStringRef) challenge.protectionSpace.host);

        SecTrustRef trustRef = NULL;
        if(policyRef)
        {
            SecTrustCreateWithCertificates((__bridge CFArrayRef) trustCertificates, policyRef, &trustRef);
            CFRelease(policyRef);
        }

        if(trustRef)
        {
//          SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef) [NSArray array]);
//          SecTrustSetAnchorCertificatesOnly(trustRef, NO);

            SecTrustResultType result;
            OSStatus trustEvalStatus = SecTrustEvaluate(trustRef, &result);
            if(trustEvalStatus == errSecSuccess)
            {
                // just temporary attempt to make it working.
                // i hope, there is no such problem, when we have final working version of certificates.
                if(result == kSecTrustResultRecoverableTrustFailure)
                {
                    CFDataRef errDataRef = SecTrustCopyExceptions(trustRef);
                    SecTrustSetExceptions(trustRef, errDataRef);

                    SecTrustEvaluate(trustRef, &result);
                }

                if(result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)
                    credential = [NSURLCredential credentialForTrust:trustRef];
            }

            CFRelease(trustRef);
        }
    }
    else
    {
        DDLogWarn(@"Unexpected authentication method. Cancelling authentication ...");
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }

    if(credential)
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    else
        [challenge.sender cancelAuthenticationChallenge:challenge];
}

在 CFNetwork 诊断日志中,我可以看到握手程序即将启动。至少应用程序发送“ClientHello”消息,然后服务器发送其“ServerHello”消息并要求进行身份验证。这里应用程序尝试发送身份验证响应,但立即收到错误。 (同时,在服务器日志中我根本没有看到任何有关握手的消息)。这是诊断日志的一部分:

Sep 15 10:51:49  AppName[331] <Notice>: CFNetwork Diagnostics [3:49] 10:51:49.185 {
    Authentication Challenge
       Loader: <CFURLRequest 0x1501931c0 [0x19f6dab68]> {url = https://217.92.80.156:9090/(method name and parameters), cs = 0x0}
    Challenge: challenge space https://217.92.80.156:9090/, ServerTrustEvaluationRequested (Hash f9810ad8165b3620)
    } [3:49]
Sep 15 10:51:49  AppName[331] <Notice>: CFNetwork Diagnostics [3:50] 10:51:49.189 {
    Use Credential
        Loader: <CFURLRequest 0x1501931c0 [0x19f6dab68]> {url = https://217.92.80.156:9090/(method name and parameters), cs = 0x0}
    Credential: Name: server, Persistence: session
    } [3:50]
Sep 15 10:51:49  AppName[331] <Notice>: CFNetwork Diagnostics [3:51] 10:51:49.190 {
     touchConnection
              Loader: <CFURLRequest 0x1501931c0 [0x19f6dab68]> {url = https://217.92.80.156:9090/(method name and parameters), cs = 0x0}
    Timeout Interval: 60.000 seconds
    } [3:51]
Sep 15 10:51:49  AppName[331] <Notice>: CFNetwork Diagnostics [3:52] 10:51:49.192 {
    Response Error
    Request: <CFURLRequest 0x14e5d02a0 [0x19f6dab68]> {url = https://217.92.80.156:9090/(method name and parameters), cs = 0x0}
      Error: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFNetworkCFStreamSSLErrorOriginalValue=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x1500ddd90 [0x19f6dab68]>{type = immutable, count = 1, values = (
                0 : <cert(0x14e6fb370) s: (server certificate name) i: (custom CA name)>
             )}, _kCFStreamPropertySSLClientCertificateState=2, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x150094100>, _kCFStreamPropertySSLClientCertificates=<CFArray 0x14e5ee8e0 [0x19f6dab68]>{type = mutable-small, count = 2, values = (
                0 : <SecIdentityRef: 0x15012cd40>
                1 : <cert(0x15014aa70) s: (client certificate name) i: (custom CA name)>
             )}, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802}
    } [3:52]

我们的后端实例可以安装在客户端,因此我无法在 Info.plist 文件中设置任何域异常。此外,应用程序可以通过 IPv4 形式的 IP 地址请求服务器,但不能通过域名(如我的示例中所示)。

我尝试过什么:

  • 使用 NSURLSession 而不是 NSURLConnection,但没有任何成功;
  • 检查了 Apple 对服务器实施的 ATS 要求here(后端开发人员确信他的实现满足所有这些要求);
  • 根据 stackoverflow 和 Apple 开发者论坛中已解决的各种问题,设置用于信任验证的锚证书;
  • 特别关注similar帖子及其相关内容solution在开发者论坛上;

我正在使用 iOS 9 GM Seed(Build 13A340)和 xCode 7 GM Seed(Build 7A218)在 iPad Air 2 上测试 https 请求。重要提示:此功能在 iOS 8 上运行良好。考虑到这一点,我可能会认为问题出在我们的服务器中,但我们的后端开发人员向我保证一切都很好。

现在我没有主意了。如果有人能给我一个提示,或者至少建议一些其他诊断,这将揭示特定的错误,比“致命警报”更具体,我将不胜感激。

Thanks.

编辑1:SecTrustEvaluate总是返回kSecTrustResultRecoverableTrustFailure,这就是为什么我必须找到某种解决方法。


根据这个:https://forums.developer.apple.com/message/36842#36842

修复 HTTP 加载失败(kCFStreamErrorDomainSSL,-9802)的最佳方法是在 info.plist 文件中设置异常,如下所示:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>test.testdomain.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>
</dict>

重要的一点是,这并不比 iOS8 更安全,只是不如 iOS9 支持的完整 ATS 安全。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用自签名证书在 iOS 9 中发出 HTTPS 请求 [关闭] 的相关文章

  • 当前 UIActivityViewController- LaunchServices:invalidationHandler 被调用

    我已经看过相关问题here and here 我已经实施了建议的答案 但没有效果 我在 UIToolbar 上有一个 UIBarButtonItem 带有用于将操作发送到 btnTBAction touch 的连接 在 ViewContro
  • 在 macOS 中以编程方式启用、禁用和启动服务

    我正在编写一个附带服务的程序 到目前为止 我所做的是创建一个辅助工具 它可以为我的进程运行提升的任务 并可以通过 XPC 进行通信 我的程序与一项服务捆绑在一起 我想使用帮助工具来安装和启动 停止该服务 以便我的程序可以在设置中具有 随系统
  • 本地主机的自签名 SSL 证书,如何使其可信

    我有一个 Owin 自托管 C 应用程序 它通过 127 0 0 1 5555 提供 Web API 服务 它只侦听本地主机 没有外部连接 这些 Web API 服务是使用 Ajax 从 AngularJS 应用程序调用的 顺便说一句 Ow
  • 将私钥添加到 X509Certificate

    我正在编写一些当前使用 OpenSSL net 为证书签名请求创建公钥 私钥对的代码 该请求配备有公钥并发送到 CA CA 返回签名证书 然后将之前创建的私钥添加到证书中 myCert PrivateKey CryptoKey FromPr
  • WebView拒绝显示图像

    我读过很多关于这个问题的帖子 其中大部分都是旧的 所以我正在创建一个新的帖子 从 React Native v0 61 5 开始 我的问题 我正在检索网页及其引用的文件 将它们写入应用程序的文档文件夹 并尝试将它们加载到 WebView 中
  • 如何使用 Objective C 收集 osx 中的系统信息

    是否定义了任何方法 API 来收集 osx 中的系统信息 我想编写一个实用程序来收集CPU RAM 网络适配器等硬件信息 任何想法 提前致谢 System Profiler 很不错 它会为一些缓慢的文件 I O 输出 XML 并且在获取所需
  • 无法在 UIPageViewController 中实现 UITextview

    我有一个奇怪的问题 我有一个页面应用程序 其中一个页面我使用了UITextView 但是当我点击UITextView它移至下一页 无法在上面写任何内容 我使用的时候没有问题UIPageViewControllerTransitionStyl
  • NSPredicate 未执行

    这很有趣 在我的应用程序中 我在数据库中创建了数千个条目 在另一个线程中 我使用 MagicalRecord 一切似乎都工作正常 从背景 前景 上下文的角度来看 当我在主线程中尝试获取 刚刚插入 的数据时 我发现了以下行为 NSArray
  • iPhone :UITableView CellAccessory 复选标记

    在 iPhone 应用程序中 单击表视图单元格我想显示表视图单元格附件类型在 didSelectRowAtIndexPath 上复选标记我正在编写代码 if indexPath row 0 tableView cellForRowAtInd
  • 为什么断言只是终止为 iPhone 编译的程序?

    我正在调试一个经过大量断言 处理的 iPhone 应用程序 Xcode Objective C 和设备模拟器 在某些情况下 断言失败只会终止应用程序 而不是像我期望的那样闯入调试器 我通过实现我自己的断言来解决方法 其效果是 define
  • 将ios 5模拟器安装到xcode 5.1?

    我目前在 Mac 10 8 5 上使用 xcode 5 1 但我无法在这个 xcode 中安装 ios 模拟器 有人告诉我如何安装ios 5模拟器吗 伙计 这个really今天 当我从 Xcode 5 0 升级到 Xcode 5 1 并发现
  • 如何使用 Swift 创建具有动态单元高度的静态单元

    我已经看过几个教程 这些教程展示了如何设置动态单元高度 但所有这些教程仅在您通过设置适当的约束并使用动态单元来使用动态单元时才显示UITableViewAutomaticDimension 但是 我想对静态单元格执行此操作 我的应用程序中有
  • Objective-C 中无延迟播放音效

    我想在人们按下我的应用程序中的某些按钮时播放一些简单的声音效果 并且我尝试了几种方法 但我总是遇到延迟 使声音看起来不同步 我已按照教程进行操作here 所以我尝试了音频服务中的构建 但是有延迟 并且我尝试了 AVAudioPlayer 但
  • 点击NSView

    我有一个NSView包含多个子视图 其中一个子视图是透明的并分层在顶部 我需要能够点击这个视图到下面的子视图 以便下面的视图获得第一响应者状态 但是所有鼠标事件都卡在顶部视图上 alpha 是1 因为我在里面画了东西 所以它应该只点击透明区
  • 当dispatch_async任务完成时我如何收到通知?

    我有一个像这样的异步任务 dispatch async dispatch get main queue myAsyncMethodsHere 有没有办法在后台任务完成时收到通知 或者在完成后调用一个方法 我已通读文档并研究了dispatch
  • 如何使用节标题调整 UITableViewController 中 UITableView 的大小

    我在 UITableViewController 中有一个分组的 UITableView 我想水平调整它的大小 我尝试了很多不同的方法 但没有一个是完美的 我尝试过的 1 覆盖 UITableView setFrame 但它没有移动各部分的
  • 在iOS中的后台线程上执行任务,即使应用程序进入后台也保持执行运行:[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 如何在后台线程上执行 即使用户按下主页按钮 执行也应在后台继续 将这些属性添加到您的 h 文件中 property nonatomic strong NSTimer updateTi
  • 传送 iOS 应用程序更新时出错。 “此捆绑包无效。Apple 目前不接受使用此版本 SDK 构建的应用程序。”

    我于 2014 年 1 月 24 日小心翼翼地向 iOS 应用商店交付了一个应用程序 这是一款仅限 iO7 iPhone 的应用程序 一切都已正确交付 截至昨天 我的应用程序已获得批准 目前在应用程序商店中可见 我整理了一个小更新 目前正在
  • Facebook SDK 使用 Swift 3 iOS 10 登录

    我通过 Cocoapods 安装了 Facebook 的 Swift SDK pod FacebookCore git gt https github com facebook facebook sdk swift pod Facebook
  • iPhone 6 状态栏显示放大的应用程序,但不在主屏幕上 [关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 经过一些初步测试 我们在 iPhone6 上的应用程序看到状态栏 也许是整个应用程序 显示缩放后的尺寸 当我说缩放时 我指的是桌面设置缩放与标准设置 该应用程序是使用旧的故事板类型编写

随机推荐

  • 在elasticsearch中使用现有字段作为id

    今天刚开始使用elasticSearch 我想知道是否可以设置某种全局参数以始终使用文档中的某个字段作为 ID 我的 JSON 文档将始终拥有自己的唯一 ID Record ID a06b0000004SWbdAAG System Mods
  • Java 和本地数据库

    TL 博士 需要一些 Java 帮助来连接到真正的本地数据库 无法访问服务器技术 或者如果您可以编写代码 那就可以了 它所要做的就是查询数据库 MS Access 尽管可以更改 并输出一个 JSON 字符串 有关更多具体信息 请参阅 EDI
  • React Native android APK 扩展支持吗?

    我尝试搜索 React Native Android APK Expansion 但找不到任何有关它的页面 RN 支持 APK 扩展文件吗 如何在本地开发中测试它 谢谢 None
  • 在spring data elasticsearch中,聚合查询不能放在存储库实现中吗?

    我第一次使用 spring boot elasticsearch 我现在已经弄清楚如何使用 elastics java api 描述我的串行差异管道查询 正如您将在下面看到的 这个查询相当大 并且为每个对象返回多个存储桶以及每个存储桶之间的
  • 丢失密钥对后访问 EC2 实例

    几个月前 我启动了一个 EC2 实例 当时我将 pem 密钥存储在我的 PC 中 电脑崩溃后 我不得不在上面重新安装 Windows 而且我没有 pem 文件的备份 有什么方法可以让我到达 EC2 实例上的提示符 任何通过 ssh 或其他方
  • ASP.Net MVC 控制器构造函数中的会话为 null

    为什么控制器的构造函数中Session为null 可以从 Action 方法访问它 据推测 因为 MVC 路由框架负责更新控制器 所以它此时还没有 重新 实例化会话 有谁知道这是否是设计使然 如果是 为什么 我已经通过使用延迟加载模式设法规
  • jackson xml 列出了识别为重复键的反序列化

    我正在尝试使用将 xml 转换为 jsonjackson 2 5 1 and jackson dataformat xml 2 5 1xml结构是从Web服务器接收的并且未知 因此我不能用java类来表示该对象 并且我试图直接转换为Tree
  • 莫西忽略场

    使用 moshi 序列化为 json 字符串时是否有一种简单的方法来忽略字段 我只能想到是一个自定义适配器 但我感觉有更好的方法 Use transient关于现场声明 private transient String your varia
  • 使用反射在内部类中实例化带有参数的构造函数

    我有一些类似的事情 object parameter new object 1 parameter 0 x object instantiatedType Activator CreateInstance typeToInstantiate
  • OpenCV - 让滑块在视频播放期间更新其位置

    我选择了 学习 OpenCV 并尝试了一些代码示例 练习 在此代码片段中 我想让滑块随着每个视频帧的变化而更新其位置 但由于某种原因它不起作用 图片通过以下代码冻结 include cv h include highgui h int g
  • 在 SELECT INTO 中保留 ORDER BY

    我有一个 T SQL 查询 它从一个表中获取数据并将其复制到一个新表中 但只复制满足特定条件的行 SELECT VibeFGEvents INTO VibeFGEventsAfterStudyStart FROM VibeFGEvents
  • 检查路径是否有效

    我只是想知道 我正在寻找一种方法来验证给定路径是否有效 注意 我不想检查文件是否存在 我只想证明路径的有效性 所以如果文件可能存在于该位置 问题是 我在 Net API 中找不到任何内容 由于 Windows 支持多种格式和位置 我宁愿使用
  • 为什么 x 在内部作用域中未定义? [复制]

    这个问题在这里已经有答案了 在下面的代码中 var x 1 function console log x var x 2 为什么console log x 时 x未定义 可变提升 实际的代码是这样执行的 var x 1 function v
  • Interface Builder > Inspector > Bindings 中的“控制器键”是什么意思?

    我在文档中找不到他们解释所有这些字段及其含义的地方 尤其是 控制器键 我不清楚 复印我在另一个问题上的回答 控制器键是您要绑定的 控制器对象的属性 的键 模型关键路径是绑定对象可以向模型对象请求更基本的对象 例如字符串或图像 或其他模型对象
  • 使用 gson 将 json 字段反序列化为纯字符串

    我正在尝试将 json 对象反序列化为 java bean 我面临的主要问题是我想对待这个领域object将 json 字符串视为普通字符串 即使它包含可能正确的 json 对象 json结构是这样的 type user object id
  • REPL 和解释器有什么区别?

    REPL 和解释器之间有技术差异吗 交互式解释器使用 REPL 不需要配备口译员 例如 您可以以非交互模式 在文件上 运行 Python 并且它不会使用读取 评估 打印循环
  • 使用 numpy fft 提取相位信息

    我正在尝试使用快速傅立叶变换来提取单个正弦函数的相移 我知道 在纸面上 如果我们将函数的变换表示为 T 那么我们有以下关系 然而 我发现虽然我能够准确捕获余弦波的频率 但除非我以极高的速率采样 否则相位不准确 例如 import numpy
  • 如何在 Windows 机器上使用 nginx 运行 django?

    我有一个 Django 项目 我已经安装了nginx服务器 我想在 Windows 机器上运行 nginx 和 django 我尝试过几个博客Nginx Django Uwsgi 但它们都需要 uwsgi 但 uwsgi 未安装在 Wind
  • 代码生成器、ORM、存储过程

    这些软件架构在哪些领域表现出色或失败 哪些关键要求会促使您选择其中一个 请假设您有可用的开发人员 他们可以完成良好的面向对象代码以及良好的数据库开发 另外 请避免圣战 所有三种技术都有优点和缺点 我感兴趣的是最适合在哪里使用哪种技术 这些工
  • 使用自签名证书在 iOS 9 中发出 HTTPS 请求 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 目前不接受答案 我想使用自签名证书向自定义服务器发出 HTTPS 请求 我正在使用 NSURLConnection 类并处理身份验证质询 但总是在控制台中收到错误消息 NSURLSessio