当我们尝试使用NSURLConnection与SSL连接不可信的证书时,有没有办法让用户选择是否信任该站点?

问题描述:

在堆栈溢出上有类似的question当我们尝试使用NSURLConnection与SSL连接不可信的证书时,有没有办法让用户选择是否信任该站点?

这是我的代码,它将接受不受信任的服务器证书。

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space 
{ 
    //We can always attempt to authenticate... 
    return YES; 
} 

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

但是,我想提出一个改变视图,让用户选择是否信任该网站。

UIAlertView *alert = [[UIAlertView alloc] initWithTitle: 
[[challenge protectionSpace]host] message:@"Do you trust this site?" 
delegate:self cancelButtonTitle:@"No" 
otherButtonTitles:@"Yes", @"Just once", nil]; 

[alert show]; 

我该怎么做?

举个例子,你可以挑战对象保存到一个属性,然后实现alertView:clickedButtonAtIndex:类似这样的委托方法(这是“信任只是一次”):

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    if(buttonIndex == alertView.cancelButtonIndex) 
    { 
     [[self.challenge sender] cancelAuthenticationChallenge:self.challenge]; 
    } 
    else 
    { 
     [self.challenge.sender useCredential:[NSURLCredential credentialForTrust:self.challenge.protectionSpace.serverTrust] forAuthenticationChallenge:self.challenge]; 
     self.challenge = nil; 
    } 
} 

如果你想要始终相信你需要做一些更复杂的事情来保存和比较服务器证书数据。或者通过保存服务器url总是可信的方式使其变得简单和不安全,这使得你在中等攻击时容易受到攻击。