在iOS 9中,AuthenticationMethodServerTrust为nil

3
我一直在尝试使用NSURLSession在我的iOS 8+应用中实现公钥固定的方法。我所做的是实现代理方法didReceiveChallenge,获取challenge.protectionSpace.authenticationMethod并检查它是否等于NSURLAuthenticationMethodServerTrust。
如果它等于NSURLAuthenticationMethodServerTrust,我会检查证书并将其与本地副本进行比较。这在iOS 8上正常工作,但在iOS 9上,我没有收到一个等于NSURLAuthenticationMethodServerTrust的认证方法。我收到的是NSURLAuthenticationMethodClientCertificate,因此无法访问challenge.protectionSpace.serverTrust属性。
有任何想法吗?
public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)
{


      if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust)
        {
            // Verify the identity of the server
                    println("Trusted")
                    return challenge.sender.performDefaultHandlingForAuthenticationChallenge!(challenge)

        }
        println("Not trusted")
        return challenge.sender.cancelAuthenticationChallenge(challenge)
    }
}

请查看以下链接:http://stackoverflow.com/questions/33542003/client-certificate-authentication-in-swift2/34014653#34014653。它可能会有所帮助。 - Karlos
嗨Karlos,这对我不起作用。 :-( 我和Victor有同样的问题。 - lûr
1个回答

3
您的回调函数可能会因不同的保护空间而被多次调用。在这里发生的是,这些调用的顺序已经改变,在iOS 9中显然没有首先发生服务器信任保护空间的调用。
问题在于您取消了第一个挑战,这实际上终止了连接。请不要这样做,而是使用“执行默认处理”。
您也可能不希望对服务器信任情况执行默认处理,因为这相当于根本没有编写自定义处理程序。相反,请检查密钥,并仅在它是所需密钥时执行默认处理,否则取消身份验证挑战。
或者我可能误读了您的代码。看起来有一些代码丢失了。可能是您根本没有处理非服务器信任情况,这就是问题所在。如果您没有为每个挑战调用“某些东西”,那么连接将永远停留在那里,等待您这样做。

1
感谢@dgatwood。你救了我的一天 :) 显然,在iOS 9中,ClientCertificateChallenge首先被调用,所以我只需添加:... else if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) { completionHandler(NSURLSessionAuthChallengeDisposition.PerformDefaultHandling, nil); } - VíctorVarLed
顺便说一下,我之前说错了。服务器信任的默认处理方式是没问题的。如果强制让它使用未经检查的证书那才是错误的。 :-) - dgatwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接