我有以下简单的代码连接到SSL网页

NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:url];
[ NSURLConnection sendSynchronousRequest: urlRequest returningResponse: nil error: &error ];

除非它给出一个错误,如果证书是自签名的一个错误域=NSURLErrorDomain Code=-1202 UserInfo=0xd29930“不受信任的服务器证书”。有没有一种方法来设置它接受连接(就像在浏览器中你可以按accept)或一种方法来绕过它?


当前回答

你必须使用NSURLConnectionDelegate来允许HTTPS连接iOS8有新的回调。

弃用:

connection:canAuthenticateAgainstProtectionSpace:
connection:didCancelAuthenticationChallenge:
connection:didReceiveAuthenticationChallenge:

相反,你需要声明:

connectionShouldUseCredentialStorage:发送以确定URL加载器是否应该使用凭据存储来验证连接。 connection:willSendRequestForAuthenticationChallenge: -告诉委托连接将发送一个身份验证挑战请求。

使用willSendRequestForAuthenticationChallenge,你可以像使用已弃用的方法一样使用challenge,例如:

// Trusting and not trusting connection to host: Self-signed certificate
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];

其他回答

您可以使用此代码

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
     if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust)
     {
         [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[[challenge protectionSpace] serverTrust]] forAuthenticationChallenge:challenge];
     }
}

使用-connection:willSendRequestForAuthenticationChallenge:代替这些已弃用的方法

弃用:

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace  
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
-(void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

NSURLRequest有一个叫做setAllowsAnyHTTPSCertificate:forHost:的私有方法,它会做你想做的事情。你可以通过一个类别在NSURLRequest上定义allowsAnyHTTPSCertificateForHost:方法,并设置它为你想要覆盖的主机返回YES。

由Nathan de Vries发布的category工作区将通过AppStore私有API检查,并且在你无法控制NSUrlConnection对象的情况下很有用。 一个例子是NSXMLParser,它将打开你提供的URL,但不公开NSURLRequest或NSURLConnection。

在iOS 4中,解决方法似乎仍然有效,但仅在设备上,模拟器不再调用allowsAnyHTTPSCertificateForHost:方法。

你必须使用NSURLConnectionDelegate来允许HTTPS连接iOS8有新的回调。

弃用:

connection:canAuthenticateAgainstProtectionSpace:
connection:didCancelAuthenticationChallenge:
connection:didReceiveAuthenticationChallenge:

相反,你需要声明:

connectionShouldUseCredentialStorage:发送以确定URL加载器是否应该使用凭据存储来验证连接。 connection:willSendRequestForAuthenticationChallenge: -告诉委托连接将发送一个身份验证挑战请求。

使用willSendRequestForAuthenticationChallenge,你可以像使用已弃用的方法一样使用challenge,例如:

// Trusting and not trusting connection to host: Self-signed certificate
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];

如果您不愿意(或不能)使用私有api,可以使用一个名为ASIHTTPRequest的开源(BSD许可)库,该库提供了底层CFNetwork api的包装器。他们最近通过- setvalidatessecureccertificate: API引入了允许使用自签名或不受信任证书的HTTPS连接的功能。如果不想提取整个库,可以使用源代码作为自己实现相同功能的参考。