ios 使用 UIWebView 忽略无效的服务器证书
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6792213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ignoring Invalid Server Certificates with UIWebView
提问by Kristopher Johnson
We have an iOS app that uses a UIWebView to display content. We load it up with data with code that looks like this:
我们有一个使用 UIWebView 来显示内容的 iOS 应用程序。我们使用如下代码加载数据:
NSURL *url = [NSURL URLWithString:myURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView setDelegate:self];
[_webView loadRequest:request];
This used to work fine with HTTP requests, but now we are using HTTPS against a server with a self-signed SSL certificate. When the above is run, the webView:didFailLoadWithError:
delegate method gets called, with this error:
这曾经适用于 HTTP 请求,但现在我们对带有自签名 SSL 证书的服务器使用 HTTPS。当上面运行时,webView:didFailLoadWithError:
委托方法被调用,并出现以下错误:
The certificate for this server is invalid. You might be connecting to a server that is pretending to be "blah.blah.blah.com" which could put your confidential information at risk."
此服务器的证书无效。您可能正在连接到一个伪装成“blah.blah.blah.com”的服务器,这可能会使您的机密信息处于危险之中。
I would like to simply ignore the invalid certificate and go on with the request, as one can do in Mobile Safari.
我想简单地忽略无效的证书并继续请求,就像在 Mobile Safari 中所做的那样。
I have seen how to work around this issue when using NSURLConnection
(see HTTPS request on old iphone 3g, for example), but what can one do with a UIWebView
?
我已经看到在使用时如何解决这个问题NSURLConnection
(例如,请参阅旧 iphone 3g 上的 HTTPS 请求),但是可以用UIWebView
?
I imagine that I could rework the code so that it uses NSURLConnection
to make the requests and then puts the results into the web view by calling its loadHTMLString:baseURL:
method, but that's going to get complicated when the pages have images, CSS, JavaScript, and so on. Is there an easier way?
我想我可以重新编写代码,以便它用于NSURLConnection
发出请求,然后通过调用其loadHTMLString:baseURL:
方法将结果放入 Web 视图中,但是当页面具有图像、CSS、JavaScript 等时,这将变得复杂。有更容易的方法吗?
回答by Darc
Please note: This API is currently unsupported, and should really only be used in a safe testing environment. For further details, take a look at this CocoaNetics article.
请注意:此 API 目前不受支持,应该只在安全的测试环境中使用。有关更多详细信息,请查看这篇CocoaNetics 文章。
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
will allow you to ignore certificate errors. You will also need to add the following to the beginning of your file to grant you access to these private APIs:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
将允许您忽略证书错误。您还需要将以下内容添加到文件的开头,以授予您对这些私有 API 的访问权限:
@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
回答by greg.casamento
Just so everyone knows... the above use of hidden interfaces WILL NOT BE ACCEPTED BY APPLE. They look for use of private APIs and it is NOT an acceptable solution. So, please do not go posting the solution described above around as THE way to fix it because, although it works, it will buy you a rejection in the AppStore. That makes it useless.
只是让每个人都知道......上述隐藏界面的使用不会被Apple接受。他们寻找私有 API 的使用,这不是一个可接受的解决方案。因此,请不要将上述解决方案作为修复它的方法发布,因为尽管它有效,但它会让您在 AppStore 中遭到拒绝。这使它毫无用处。
What follows is the ACCEPTABLE method of ignoring invalid server certificates. You need to use NSURLConnection and load the data for the webpage manually like so:
下面是忽略无效服务器证书的 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];
}
And then, in your delegate....
然后,在你的代表中......
- (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
Where resultData is an NSMutableData you instantiated earlier and where url and urlAddress are both things you've instantiated and filled in elsewhere.
其中 resultData 是您之前实例化的 NSMutableData,而 url 和 urlAddress 都是您已实例化并在其他地方填充的内容。
Unfortunately, I currently don't know a way to get the actual UIWebView to load a page directly without having a valid certificate.
不幸的是,我目前不知道如何在没有有效证书的情况下让实际的 UIWebView 直接加载页面。
Yours, GC
你的,GC
回答by Prof Von Lemongargle
It turns out that once the site is authenticated by a cancelled NSURLConnection, the UIWebView can make requests to the site. There is a complete explanation here.
事实证明,一旦站点通过取消的 NSURLConnection 进行身份验证,UIWebView 就可以向站点发出请求。这里有一个完整的解释。
回答by Greg
As far as I know, that isn't possible with just UIWebView
. As I understand it, you need to use NSURLConnection
to handle all the HTTP/HTTPS mojo and then feed its results to the UIWebView
via -loadHtmlString:baseURL:
or -loadData:MIMEType:textEncodingName:baseURL:
.
据我所知,仅使用UIWebView
. 据我了解,您需要使用NSURLConnection
来处理所有 HTTP/HTTPS mojo,然后将其结果提供给UIWebView
via-loadHtmlString:baseURL:
或-loadData:MIMEType:textEncodingName:baseURL:
.