【问题标题】:willSendRequestForAuthenticationChallenge method is called recursivewillSendRequestForAuthenticationChallenge 方法被称为递归
【发布时间】:2017-02-15 15:34:25
【问题描述】:

我正在使用 iOS 10。我正在评估自签名证书,如下所示

-(void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];

    if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) {

        SecTrustRef trust = [protectionSpace serverTrust];

        SecPolicyRef policyOverride = SecPolicyCreateSSL(true, (CFStringRef)@"HOSTNAME");
        SecTrustSetPolicies(trust, policyOverride);

        CFMutableArrayRef certificates = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);

        /* Copy the certificates from the original trust object */
        CFIndex count = SecTrustGetCertificateCount(trust);
        CFIndex i=0;
        for (i = 0; i < count; i++) {
            SecCertificateRef item = SecTrustGetCertificateAtIndex(trust, i);
            CFArrayAppendValue(certificates, item);
        }

        /* Create a new trust object */
        SecTrustRef newtrust = NULL;
        if (SecTrustCreateWithCertificates(certificates, policyOverride, &newtrust) != errSecSuccess) {
            /* Probably a good spot to log something. */
            NSLog(@"Error in SecTrustCreateWithCertificates");
            [connection cancel];
            return;
        }

        CFRelease(policyOverride);

        /* Re-evaluate the trust policy. */
        SecTrustResultType secresult = kSecTrustResultInvalid;
        if (SecTrustEvaluate(trust, &secresult) != errSecSuccess) {

            /* Trust evaluation failed. */
            [connection cancel];

            // Perform other cleanup here, as needed.
            return;
        }

        switch (secresult) {
                //case kSecTrustResultInvalid:
                //case kSecTrustResultRecoverableTrustFailure:
            case kSecTrustResultUnspecified: // The OS trusts this certificate implicitly.
            case kSecTrustResultProceed: // The user explicitly told the OS to trust it.
            {
                NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];

                return;
            }
            default: ;
                /* It's somebody else's key. Fall through. */
                [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
                break;
        }
        /* The server sent a key other than the trusted key. */
        [connection cancel];
        // Perform other cleanup here, as needed.
    }
}

评估后的结果是“kSecTrustResultUnspecified”,同样的方法“willSendRequestForAuthenticationChallenge”再次被递归调用。不确定为什么递归调用该方法。如果代码有任何问题,请告诉我。

谢谢

【问题讨论】:

    标签: ios ssl ios10 secure-transport


    【解决方案1】:

    对此有几个解决方案,我认为最简单的一个是here。综上所述,需要勾选[challenge previousFailureCount],防止重复进入方法。

    否则,从 Apple API 文档中,我会建议类似于 this 的内容,它使用已弃用的委托回调,但可能对您有用。

    【讨论】:

    • 在方法 'willSendRequestForAuthenticationChallenge' if ([challenge previousFailureCount]) { [[challenge sender] cancelAuthenticationChallenge:challenge]; } 执行在 if 条件下不进入这里。
    • 那么previousFailureCount 是0,那么呢?
    • 无法打印该值,因为它不属于如果条件我认为它应该是 0 那么。
    【解决方案2】:

    它实际上是递归调用的。您的代码应该处理这个问题。

    起初看起来很奇怪,但它有点道理......尝试进行身份验证,失败,所以它回到相同的方法(谁知道,也许你想尝试不同的凭据或其他东西)。

    您可以检查之前的失败计数并自己拒绝它,否则它将失败并继续返回您的函数以递归方式进行身份验证,就像目前正在发生的那样。

    【讨论】:

    • [challenge previousFailureCount] 总是返回 0。如果我遗漏了什么,你能告诉我吗
    猜你喜欢
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2021-08-09
    • 2020-10-01
    • 1970-01-01
    相关资源
    最近更新 更多