Pop the Proxy Authentication dialog in iOS real device

I've configured a proxy for the NSURLSessionConfiguration object in my app, the proxy use the "Digest" authentication scheme and this occurs only within HTTPS requests.

Normal in Simulator, but popup a dialog stating the proxy authentication is required and gives the user the choice to do this "later" or directly go to the system settings in iPhone real device.

In addition, the dialog pops up even before the delegate method "URLSession:task:didReceiveChallenge:completionHandler:", the application does not get an opportunity to provide credentials before iOS displays it, but it's very strange that click on "later" will execute the delegate.


demo code

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    config.connectionProxyDictionary = @{
                                         @"HTTPEnable" : @(1),
                                         (NSString *)kCFStreamPropertyHTTPProxyHost  : @"proxy.xxxx.com",
                                         (NSString *)kCFStreamPropertyHTTPProxyPort  : @(1234),
                                         @"HTTPSEnable": @(1),
                                         (NSString *)kCFStreamPropertyHTTPSProxyHost : @"proxy.xxxx.com",
                                         (NSString *)kCFStreamPropertyHTTPSProxyPort : @(1234)
                                        };
    self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:RequestUrl] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];

    NSURLSessionTask  *task =  [self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    //    NSLog(@"resultData:%@  error: %@",data, error.description);
    }];
    [task resume];


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler
{
   // NSLog(@"task:%@",challenge.protectionSpace.authenticationMethod);

    if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPDigest) {
        NSURLCredential *cren = [NSURLCredential credentialWithUser:FLOW_UNICOM_KEY password:FLOW_UNICOM_SECRET persistence:NSURLCredentialPersistenceNone];
        if (completionHandler) {
            completionHandler(NSURLSessionAuthChallengeUseCredential,cren);
        }
    }
    if (completionHandler) {
        //completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,nil);
    }
}

Replies

You haven’t actually asked a question here, but I’m going to assume that you’re asking:

  • Is this a bug? — IMO the answer is yes; the session delegate should always get first crack at authentication challenges. System infrastructure, like this dialog, should only kick in if you resolve the challenge with

    .performDefaultHandling
    .

    While I’ve seen reports of this before, I still recommend that you file your own bug report about this. Please post your bug number, just for the record.

  • Is there a workaround? — Not a good one. One option is to change your proxy to do some other form of authentication (for example, you could have it authenticate based on some custom key that your app always sets on requests) but that’s less than ideal.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for the reply!

I've now filed a bug report (#29675140).

Dear Eskimo

I had the same situation, when I use the NSURLSession to request https and set "Digest" authentication, then showing a dialog box , I need to make a choice to set now or later into the setting system.

To slove the pop-up dialogue problem with using delegate way "proxyAuthenticationNeededForRequest:" in network requests in ASIHTTPRequest.

So I wondered is there any way similar to ASIHTTPRequest to avoid popping up the dialog box when I use NSURLSession.


Thanks!

ASIHTTPRequest is based on the now-deprecated CFHTTPStream, where you have to handle both proxies and authentication yourself. CFHTTPStream is not integration with the system proxy support and thus doesn’t suffer from this problem.

I don’t recommend you use ASIHTTPRequest because, as I said, it’s based on deprecated technology. The other potential workarounds that I know of are:

  • If you regress to Basic authentication, you can set the

    Authorization
    header on the request and that often prevents the proxy from challenging at all. This is less than ideal — technically that header is reserved within the NSURLSession architecture — but it’s easy to implement and doesn’t require any server side changes.
  • You can change how the server authenticates clients, per the last point in my post of 14 Dec.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 5 Jun through to Fri, 9 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face. http://developer.apple.com/wwdc/