Scofield Tran
Scofield Tran

Reputation: 840

How can I detect UIWebview loads an url that needs authentication or not in iOS

I'm making an iOS application that allows 2 users interact with each other. When first user navigates to a URL on his app using UIWebView, I will send this url to the second user. The second user receive this link and use UIWebView to load it.

Everything works well until one person goes into a private zone. For example, when the first user goes to www.google.com and logs into his gmail account. Now I capture this link and send to the second user, who tries to load it, but this fails, because it's a private zone of the first user.

How can the UIWebView of second user know that the received url is in private zone or must authenticate to access it?

Here some illustration codes:

On the first user, when navigates an url like www.google.com. I call this function

 - (void)loadRequestUrl:(NSString *)url {
       NSLog(@"load request");

       //Load request
       self.websiteUrl = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
       NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:websiteUrl]];
      [wbWebview loadRequest:request];

      //Send url to partner
      //I'm using GCDAsyncSocket to send this url string to our server
      //And server will send it to my current partner

      //Just example code for sending
      [asyncSocket send:url];
}

//On second user. I received url string from a delegate of GCDAsyncSocket. In this delegate I call this function

- (void)receiveUrl:(NSString *)url {

      //Just Load request

      self.websiteUrl = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

      NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:websiteUrl]];

      [wbWebview loadRequest:request];

}

Here an example of url that on first user after he logins his google account https://accounts.google.com.vn/accounts/SetSID?ssdc=1&sidt=ALWU2cscH%252BVqOOjXXIRKgtz4Q8qmIcJ5lE0dy7xh7MISa%252Bw75BNSeOrF3cO91IED8Cy6PfREuDjuXLzdOMEPaaP0p6XZpCzJFQi4w2xAZa9VKubLQ5xk5%252FF%252FOj8KR0f6e5PSav%252Fww0mKEAuPoI0Dtnve600Pj6PERFtvlH3kbt2Y0hk4KEBpn6nk7zAXUdt2wc%252FaHK0%252FufzyfIMI2hkLpCFu1W1XaOIS3zwuGttA5tXjyLb3AeBLmPgfBbsd7hwZWp7IRVJGglde8gAJ%252F%252BmIhQD4eMQa1s7LD8tnuoagx%252BmRzQ4EGqtcAlE%252FGE3e8b1itkh2HXZQZYB612X1NpcPgta1XbgO7IHd0g7HsDEnsqodhHtr9F7vGl4fO%252BCcHFYaHjH3dT2mCjnOwBn%252Bbh0%252FykYpxqbx2W8K%252BHcZp3B4KI166qCPCZvgnvq7QACPsPuWGVrll4Nw2yLK%252FE2bdmFVILfgIpVbY9SheA%253D%253D&continue=http%253A%252F%252Fwww.google.com.vn%252F%253Fgfe_rd%253Dcr%2526ei%253Dgf7EU-TLL-zV8ge_rYCIAw

The second user receives it, but cannot open. I can NOT capture error on any delegate

IMPORTANCE: I don't need to force second user open it, I just want to capture the event to tell the second user that first user went into private zone

Upvotes: 0

Views: 2203

Answers (2)

Sandip
Sandip

Reputation: 176

to get user name and password , there are multiple ways of doing it , you can create your own mechanism for the same .One simple way is.

-

(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:    (NSURLAuthenticationChallenge *)challenge{

NSLog(@"Need Authentication");

UIAlertView *webLogin = [[UIAlertView alloc] initWithTitle:@"Auth" 
                                                   message:@"Enter User and Password" 
                                                   delegate:self 
                                                   cancelButtonTitle:@"Cancel" 
                                                   otherButtonTitles:@"OK"
                                                   , nil];

self. challenge = challenge;
webLogin.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
[webLogin show];
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

user = [[alertView textFieldAtIndex:0]text];
pass = [[alertView textFieldAtIndex:1]text];

if (buttonIndex == [alertView cancelButtonIndex]) {

    [self dismissModalViewControllerAnimated:YES];
}
else if (buttonIndex != [alertView cancelButtonIndex]) {

    [self handleChallenge:self.challenge withUser:user password:pass];
}


}

- (void)handleChallenge:(NSURLAuthenticationChallenge *)aChallenge     withUser:(NSString *)userName password:(NSString *)password {

NSURLCredential *credential = [[NSURLCredential alloc]
                               initWithUser:userName password:password
                               persistence:NSURLCredentialPersistenceForSession];
[[aChallenge sender] useCredential:credential forAuthenticationChallenge:aChallenge];

}

Upvotes: 3

Sandip
Sandip

Reputation: 176

To receive and handle authentication challenge in uiwebview , here is the code.

- (void)viewDidLoad
{ 

// Load the web view with your url
  [webView loadRequest:[NSURLRequest requestWithURL:[NSURL      URLWithString:@"yoururl"]]];
  isauth = NO;
}

Now for the delegates. This one is called before a new request is loaded into the webview.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{

  if (!isauth) {
    isauth = NO;
    [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
    return NO;
  }
  return YES;
}


//in nsurlconnections delegate. This one deals with the authentication challenge. this time set isauth to YES

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{

  if ([challenge previousFailureCount] == 0) {
    isauth = YES;
    [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password"  persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge];
  }
  else
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
}

// if the authentication is successfully handled than you will get data in this method in which you can reload web view with same request again.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
  NSLog(@"received response via nsurlconnection");

  NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL   URLWithString:@"yoururl"]];

  [webView loadRequest:urlRequest];
}

- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
{
  return NO;
}

Hope it helps.

thank you.

Upvotes: 3

Related Questions