Игнорирование недопустимых сертификатов сервера с помощью UIWebView
У нас есть приложение iOS, которое использует UIWebView для отображения контента. Мы загружаем его данными с кодом, который выглядит так:
NSURL *url = [NSURL URLWithString:myURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView setDelegate:self];
[_webView loadRequest:request];
Это хорошо работает с HTTP-запросами, но теперь мы используем HTTPS для сервера с самоподписанным сертификатом SSL. Когда выполняется вышеописанный вызов, вызываемый метод делегата webView:didFailLoadWithError:
вызывается с этой ошибкой:
Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, который притворяется "blah.blah.blah.com", который может угрожать вашей конфиденциальной информации ".
Я хотел бы просто игнорировать недействительный сертификат и продолжать с запросом, как это можно сделать в Mobile Safari.
Я видел, как обойти эту проблему при использовании NSURLConnection
(см. HTTPS-запрос на старом iphone 3g), но что можно сделать с помощью a UIWebView
?
Я предполагаю, что я мог бы переработать код так, чтобы он использовал NSURLConnection
, чтобы делать запросы, а затем помещает результаты в веб-представление, вызывая его метод loadHTMLString:baseURL:
, но это будет усложняться, когда страницы имеют изображения, CSS, JavaScript и т.д. Есть ли более простой способ?
Ответы
Ответ 1
Обратите внимание. Этот API в настоящее время не поддерживается, и его следует использовать только в безопасной тестовой среде. Для получения дополнительной информации ознакомьтесь с этой статьей CocoaNetics.
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
позволит вам игнорировать ошибки сертификата. Вам также необходимо добавить следующее в начало файла, чтобы предоставить вам доступ к этим частным API:
@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
Ответ 2
Просто чтобы все знали... вышеупомянутое использование скрытых интерфейсов НЕ ПРИНИМАЕТСЯ APPLE. Они ищут использование частных API, и это НЕ приемлемое решение. Поэтому, пожалуйста, не отправляйте решение, описанное выше, как способ исправить его, потому что, хотя он работает, он купит вам отказ в AppStore. Это делает его бесполезным.
Далее следует метод ACCEPTABLE игнорирования недопустимых сертификатов сервера. Вам необходимо использовать NSURLConnection и вручную загрузить данные для веб-страницы следующим образом:
.
.
.
//Create a URL object.
url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:requestObj delegate:self];
[connection start];
}
А потом, в вашем делетете....
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
else
{
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[resultData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *htmlString = [[NSString alloc] initWithBytes:[resultData bytes] length:[resultData length] encoding:NSUTF8StringEncoding];
[webView loadHTMLString:htmlString baseURL:url];
}
@end
Где resultData - это NSMutableData, которую вы создали ранее, и где url и urlAddress - это то, что вы создали и заполнили в другом месте.
К сожалению, я в настоящее время не знаю, как получить фактический UIWebView для загрузки страницы напрямую без наличия действительного сертификата.
Твой, GC
Ответ 3
Оказалось, что как только сайт будет аутентифицирован отмененным NSURLConnection, UIWebView может делать запросы на сайт. Здесь есть полное объяснение.
Ответ 4
Насколько я знаю, это невозможно с помощью только UIWebView
. Насколько я понимаю, вам нужно использовать NSURLConnection
для обработки всех HTTP/HTTPS mojo, а затем передать свои результаты в UIWebView
через -loadHtmlString:baseURL:
или -loadData:MIMEType:textEncodingName:baseURL:
.