From: http://www.cocoachina.com/bbs/read.php? Tid-55317-fpage-61.html
Several methods for accessing HTTPS sites in uiwebview have been studying how to use uiwebview to access HTTPS sites over the past two days. Many methods have been tried, but they all have such defects, I would like to share some comments with you below:
1. Call Private APIs
The simplest and most dangerous method is to call setallowsanyhttpscertificate: forhost. I don't need to talk about the consequences.
2. libcurl
This is an open-source project. The URL conversion library written in C language is based on OpenSSL and supports most of the current URLs, including dict, file, FTP, ftps, Gopher, HTTP, HTTPS, IMAP, IMAPs, LDAP, LDAPS, POP3, pop3s, rtmp, RTSP, SCP, SFTP, SMTP, smtps, telnet, and TFTP, in addition, this API will not be used by Apple, so it can pass the App Store review smoothly. However, one problem is that you need to compile the libcurl and OpenSSL static libraries by yourself. The configuration is troublesome. Friends who are not familiar with compiling static libraries in Unix may frown. There are two links available for reference:
Http://www.therareair.com/2009/01/01/tutorial-how-to-compile-openssl-for-the-iphone/
Http://www.yifeiyang.net/iphone-web-development-skills-of-the-article-5-https-server-using-libcurl-to-connect/
After the compilation is successful, introduce libcurl into the project and add the following code to access the HTTPS site.
/************** Call libcurl to access the HTTPS site ****************
Const char * urlstring = [homeurl cstringusingencoding: nsutf8stringencoding];
Curl * curl;
Curlcode res;
Char * buffer;
Int buckets FLEN = 1024;
Size_t * N;
Curl = curl_easy_init ();
If (curl ){
Curl_easy_setopt (curl, curlopt_url, "https: // 10.20.7.236/login. aspx? Returnurl = % 2f ");
// Curl_easy_setopt (curl, curlopt_url, urlstring );
Curl_easy_setopt (curl, curlopt_ssl_verifypeer, 0l );
Res = curl_easy_perform (curl );
If (0! = Res ){
Fprintf (stderr, "curl error: % d/N", Res );
}
// Res = curl_easy_recv (curl, buffer, buflen, N );
// Printf ("% s", buffer );
Curl_easy_cleanup (curl );
}
**************************************** *************/
Through online debugging, I successfully accessed the HTTPS site on my iPod. On the console, I can see the content of the webpage. The rest is how to store the content in a character array, you can call the loadhtmlstring method of uiwebview to display the content. However, I have not found a method for this last step. I hope any friends who are interested can help me solve this problem.
3. Asihttprequest
This open-source project has been popular for a long time, but it is generally used to replace nsurlconnection. In fact, its functions are quite powerful, but I am not satisfied with the HTTPS access,
There is a way to directly ignore certificate verification,
Disabling secure Certificate Validation
You may wish to use this for testing purposes if you have a self-Signed secure certificate. I recommend purchasing a certificate from a trusted Certificate Authority and Leaving Certificate Validation turned on for production applications.
[Request setvalidatessecurecertificate: No];
But it is a little dangerous to do so. If it is deployed in an enterprise environment, people outside the company can access internal websites. The SSL layer is essentially a virtual one. So I found another way to set the client certificate:
Client certificates support
If your server requires the use of client certificates, as of v1.8 it is now possible to send them with your request.
// Will send the certificate attached to the identity (identity is a secidentityref)
[Request setclientcertificateidentity: identity];
// Add an additional certificate (where cert is a seccertificateref)
[Request setclientcertificates: [nsarray arraywithobject :( ID) cert];
There is a helper function in 'clientcertificatetests. M' in the iPhone/iPad sample app that can create a secidentityref from PKCS12 data (this function only works on iOS ).
This method needs to put the p12 file into the project, and then call [clientcertificatetest extractidentity: & identity andtrust: & Trust frompkcs12data: pkcs12data]; To obtain the identity
This method is as follows:
+ (Bool) extractidentity :( secidentityref *) outidentity andtrust :( sectrustref *) outtrust frompkcs12data :( nsdata *) inpkcs12data
{
Osstatus securityerror = errsecsuccess;
Nsdictionary * optionsdictionary = [nsdictionary dictionarywithobject: @ "" forkey :( ID) ksecimportexportpassphrase];
Cfarrayref items = cfarraycreate (null, 0, 0, null );
Securityerror = secpkcs12import (cfdataref) inpkcs12data, (cfdictionaryref) optionsdictionary, & items );
If (securityerror = 0 ){
Cfdictionaryref myidentityandtrust = cfarraygetvalueatindex (items, 0 );
Const void * tempidentity = NULL;
Tempidentity = cfdictionarygetvalue (myidentityandtrust, ksecimportitemidentity );
* Outidentity = (secidentityref) tempidentity;
Const void * temptrust = NULL;
Temptrust = cfdictionarygetvalue (myidentityandtrust, ksecimportitemtrust );
* Outtrust = (sectrustref) temptrust;
} Else {
Nslog (@ "failed with error code % d", (INT) securityerror );
Return no;
}
Return yes;
}
This method must be referenced to security. framework framework (I did not reference this framework for the first time, and the result returned an error. I think there is still something wrong with the official stuff. After being depressed for a long time, I found that this framework was not referenced and dizzy ). Then, you can access the HTTPS website through [asihttprequest startsynchronous. Why? Because I have not tried it out, hehe zookeeper may be a certificate problem, I have in extractidentity: & identity andtrust: & Trust frompkcs12data: the securityerror obtained in the pkcs12data method is-26275. After searching for the data online for a long time, no result is found. Therefore, the result can only be put on hold temporarily.
-(Void) viewhomepage {
Nsurl * url = [nsurl urlwithstring: homeurl];
Nsbundle * bundle = [nsbundle mainbundle]; // obtain the mainbundle
Nsstring * plistpath = [bundle pathforresource: @ "root" oftype: @ "plist"]; // obtain the file path
// Or can be written
// Nsstring * plistpath = [[nsbundle mainbundle] pathforresource: @ "file name" oftype: @ "plist"];
// Read to an nsdictionary
Nsarray * array = [[nsarray alloc] initwithcontentsoffile: plistpath];
Nsdictionary * dictionary = [array objectatindex: 1];
Nsuserdefaults * defaults = [nsuserdefaults standarduserdefaults];
[Defaults registerdefaults: dictionary];
Bool needauthentication = [defaults boolforkey: @ "needauth"];
Secidentityref identity = NULL;
Sectrustref trust = NULL;
Nsdata * pkcs12data = [nsdata datawithcontentsoffile: [[nsbundle mainbundle] pathforresource: @ "ioa.bingosoft.net" oftype: @ "pfx"];
[Senchashellviewcontroller extractidentity: & identity andtrust: & Trust frompkcs12data: pkcs12data];
// ****************** Call asihttprequest to access the HTTPS site *************** *
Asihttprequest * request = [asihttprequest requestwithurl: url];
[Request setclientcertificateidentity: identity];
// [Request setvalidatessecurecertificate: No];
// [Request startsynchronous];
[Request setvalidatessecurecertificate: needauthentication];
[Request startsynchronous];
Nserror * error = [Request Error];
If (! Error ){
[Self. Viewer loadhtmlstring: [Request responsestring] baseurl: [request URL];
}
Else {
Nslog (@ "error: % @", error );
}
}
4. Official API
The last one is the official API. It should be put at the beginning, because it is official, but in fact I have never tried it, so I doubt its authenticity, however, someone may have succeeded, so let's discuss it.
Simply put, the two nsurlconnection delegate methods are used to ignore authentication. certificate authentication has official documents, but the official documents are too long for me to read them, so there is no further research.
-(Bool) connection :( nsurlconnection *) connection canauthenticateagainstprotectionspace :( nsurlprotectionspace *) protectionspace {
Return [protectionspace. authenticationmethod isinclutostring: nsurlauthenticationmethodservertrust];
}
-(Void) connection :( nsurlconnection *) connection didreceiveauthenticationchallenge :( nsurlauthenticationchallenge *) challenge {
If ([challenge. protectionspace. authenticationmethod isinclutostring: nsurlauthenticationmethodservertrust])
// If ([trustedhosts containsobject: Challenge. protectionspace. Host])
[Challenge. Sender usecredential: [nsurlcredential credentialfortrust: Challenge. protectionspace. servertrust]
Forauthenticationchallenge: Challenge];
[Challenge. Sender continuewithoutcredentialforauthenticationchallenge: Challenge];
}