Подтвердить что ты не робот

Игнорирование недопустимых сертификатов сервера с помощью 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 и т.д. Есть ли более простой способ?

4b9b3361

Ответ 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:.