简体   繁体   English

willSendRequestForAuthenticationChallenge方法称为递归

[英]willSendRequestForAuthenticationChallenge method is called recursive

I am using iOS 10. I am evaluating a self signed certificate as below 我正在使用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.
    }
}

The result after evaluating is ' kSecTrustResultUnspecified ' and again the same method ' willSendRequestForAuthenticationChallenge ' is being called recursively. 评估后的结果是' kSecTrustResultUnspecified ',并且再次以递归方式调用相同的方法' willSendRequestForAuthenticationChallenge '。 Not sure why the method is being called recursively. 不确定为什么要递归调用该方法。 Let me know any issue with the code. 让我知道代码的任何问题。

Thanks 谢谢

There are a couple of solutions to this, and I think the simplest one is found here . 有几个解决方案,我认为这里最简单的解决方案。 In summary, you need to check [challenge previousFailureCount] to prevent reentering the method over and over. 总之,您需要检查[challenge previousFailureCount]以防止反复重新输入方法。

Otherwise, from the Apple API documentation, I would suggest something similar to this , which uses a deprecated delegate callback, but could possibly function for you. 否则,从Apple API文档中,我会建议类似于此的内容 ,它使用不推荐的委托回调,但可能适合您。

It is actually meant to be called recursively. 它实际上是指递归调用。 Your code should handle this. 你的代码应该处理这个。

Seems weird at first, but it kind of makes sense... tries to authenticate, fails, so it comes back to the same method (who knows, maybe you want to try a different credential or something). 一开始似乎很奇怪,但它有点意义......尝试进行身份验证,失败,所以它回到同一个方法(谁知道,也许你想尝试不同的凭证或其他东西)。

You can check the previous failure count and reject it yourself, otherwise it will fail and keep returning to your function to authenticate recursively, as is currently happening. 您可以检查先前的失败计数并自行拒绝,否则它将失败并继续返回您的函数以递归进行身份验证,就像当前发生的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM