[编辑提供更多信息]
(我没有使用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) { }];