Tuesday 22 March 2011

Authentication in UIWebView and NSURLConnection (Documented API)

in IOS 4.3, you cannot use private API :

@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end

for ignoring https certificate. I have been using this method for several projects, doing testing before the app is release. testing url that my client gave to me wasn't trusted site. thus, we need to ignore authentication on that site.

 Solution:

implement NSURLConnection delegate : document api

  • – connection:canAuthenticateAgainstProtectionSpace:  delegate method
  • – connection:didReceiveAuthenticationChallenge:  delegate method

when you are using NSURLConnection, implement two of this method. (don't forget to delegate your NSURLConnection).


NSURLConnection *theConnection=[[[NSURLConnection allocinitWithRequest:theRequest delegate:self]autorelease];


then impelent 2 of these delegate :

#pragma mark - NSURLConnection 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];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}


If you are using UIWebView only, add this inside webView:shouldStartLoadWithRequest:navigationType:
 (don't forget to delegate your NSURLConnection).

[NSURLConnection connectionWithRequest:request delegate:self];

Then add 2 NSURLConnection delegate above. you UIWebView will ignore base on your NSURLConnection.




Note:

  • You may check ASIHTTPConnection to do the same and easier. 
  • This checking only requires once. you don't need to add this delegate everytime you connect to your site.
  • when using UIWebView + NSURLConnection, make sure you have boolean to check that [NSURLConnection connectionWithRequest:request delegate:self]; only done once. set boolean off to disable :
    if (!isAuth) {
isAuth = YES;
[NSURLConnection connectionWithRequest:request delegate:self];
}

  • declare isAuth in header file. it will set default to NO. 
  • close connection in didReceiveResponse:
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[connection cancel];
connection=nil;
}




Happy coding :). leave a comment if you like / have another approach.

No comments:

Post a Comment