iOS / Cocoa – NSURLSession – 处理基本的HTTPS授权

[编辑提供更多信息]

(我没有使用AFNetworking进行这个项目,我可能会在将来这样做,但是首先要解决这个问题/误会)

服务器设置

我无法在这里提供真正的服务,但它是一种简单可靠的服务,可以根据以下URL传回XML:

https://username:password@example.com/webservice

我想使用GET通过HTTPS连接到URL,并确定任何身份验证失败(http状态代码401).

我已经确认Web服务可用,并且可以成功(http状态码200)使用指定的用户名和密码从URL获取XML.我已经通过网络浏览器和AFNetworking 2.0.3和使用NSURLConnection完成了这一点.

我也确认我正在各个阶段使用正确的证书.

给出正确的凭据和以下代码:

// Note: NO delegate provided here.
self.sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig
                                  delegate:nil
                             delegateQueue:nil];

NSURLSessionDataTask *dataTask = [self.session dataTaskWithURL:self.requestURL     completionHandler: ...

上面的代码将工作.它将成功连接到服务器,获取http状态码为200,并返回(XML)数据.

问题1

在凭据无效的情况下,这种简单的方法失败.在这种情况下,完成块从不被调用,不提供状态码(401),最终任务超时.

试验解决方案

我分配了一个代表到NSURLSession,并处理以下回调:

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,NSURLCredential *credential))completionHandler
{
    if (_sessionFailureCount == 0) {
        NSURLCredential *cred = [NSURLCredential credentialWithUser:self.userName password:self.password persistence:NSURLCredentialPersistenceNone];        
    completionHandler(NSURLSessionAuthChallengeUseCredential,cred);
    } else {
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil);
    }
    _sessionFailureCount++;
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,NSURLCredential *credential))completionHandler
{
    if (_taskFailureCount == 0) {
        NSURLCredential *cred = [NSURLCredential credentialWithUser:self.userName password:self.password persistence:NSURLCredentialPersistenceNone];        
        completionHandler(NSURLSessionAuthChallengeUseCredential,nil);
    }
    _taskFailureCount++;
}

问题1使用试验溶液时

请注意使用ivars _sessionFailureCount和_taskFailureCount.我正在使用这些,因为挑战对象的@previousFailureCount属性从不提前!它始终保持为零,无论这些回调方法被调用多少次.

问题2使用试验溶液时

尽管使用正确的凭据(通过成功使用无代理证明证明),认证失败.

发生以下回调:

URLSession:didReceiveChallenge:completionHandler:
(challenge @ previousFailureCount reports as zero)
(_sessionFailureCount reports as zero)
(completion handler is called with correct credentials)
(there is no challenge @error provided)
(there is no challenge @failureResponse provided)


URLSession:didReceiveChallenge:completionHandler:
(challenge @ previousFailureCount reports as **zero**!!)
(_sessionFailureCount reports as one)
(completion handler is called with request to cancel challenge)
(there is no challenge @error provided)
(there is no challenge @failureResponse provided)

// Finally,the Data Task's completion handler is then called on us.
(the http status code is reported as zero)
(the NSError is reported as NSURLErrorDomain Code=-999 "cancelled")

(NSError还提供了一个NSErrorFailingURLKey,它显示了URL和凭据是正确的.)

欢迎任何建议!

解决方法

您不需要为此执行代理方法,只需在请求上设置授权HTTP头,例如.
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://whatever.com"]];

NSString *authStr = @"username:password";
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat: @"Basic %@",[authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:@"Authorization"];

//create the task
NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {

 }];

以上是来客网为你收集整理的iOS / Cocoa – NSURLSession – 处理基本的HTTPS授权全部内容,希望文章能够帮你解决iOS / Cocoa – NSURLSession – 处理基本的HTTPS授权所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。