具有自签名证书的NSURLSession +服务器
我有一个生产的应用程序,以及具有自签名证书的开发服务器。
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
我试图testingNSURLSession
和后台下载,但似乎无法通过- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
当我使用NSURLConnection
我可以绕过它使用:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { NSLog(@"canAuthenticateAgainstProtectionSpace %@", [protectionSpace authenticationMethod]); return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; } - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSLog(@"didReceiveAuthenticationChallenge %@ %zd", [[challenge protectionSpace] authenticationMethod], (ssize_t) [challenge previousFailureCount]); [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; }
但我不知道如何得到这个与NSURLSession
> 🙁
这是我目前(这是行不通的):
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSLog(@"NSURLSession did receive challenge."); completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); }
我也尝试创build一个NSURLSession
的类别,允许主机的任何证书:
#import "NSURLRequest+IgnoreSSL.h" @implementation NSURLRequest (IgnoreSSL) + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host { return YES; } + (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host {} @end
这似乎也没有帮助。
编辑
我已经更新了这个方法来返回:
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { //Creates credentials for logged in user (username/pass) NSURLCredential *cred = [[AuthController sharedController] userCredentials]; completionHandler(NSURLSessionAuthChallengeUseCredential, cred); }
哪还是什么都不做。
对我来说,你的第一个例子工作正常。 我已经testing了下面的代码没有问题(这当然是非常不安全的,因为它允许任何服务器证书)。
@implementation SessionTest - (void) startSession { NSURL *url = [NSURL URLWithString:@"https://self-signed.server.url"]; NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]]; NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if(error == nil) { NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; NSLog(@"Data: %@",text); } else { NSLog(@"Error: %@", error); } }]; [dataTask resume]; } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); } @end
更新:这是类接口,SessionTest类是NSURLSessionDataDelegate,要启动数据下载你创build一个SessionTest对象并调用startSession方法。
@interface SessionTest : NSObject <NSURLSessionDelegate> - (void) startSession; @end
没有足够的信息来为您的问题提出具体的解决scheme。
这里有一些主要要求:
-
既然你想要一个后台任务,确保你通过
backgroundSessionConfiguration:
创build了一个合适的NSSession
对象。 使用这个类工厂方法是获得后台会话的必要条件。 -
对于在单独进程中在后台运行的请求,仅支持上载和下载任务。 请注意,在您的原始代码中,您正在使用数据任务。
-
确保您已正确实施委托方法
application:handleEventsForBackgroundURLSession:completionHandler:
在您的应用程序委托中。 当你的应用程序没有运行,当会话在自己的进程中运行,并需要凭据,iOS将在后台重新启动你的应用程序,后台会话将调用这个委托方法。 另见https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:handleEventsForBackgroundURLSession:completionHandler :
禁用服务器信任评估应按照您在第一个示例中尝试的方式工作。 只用于开发!
- 日历:获取date组件,奇怪的情况
- 自动resize的UITableView头旋转(大部分在iPad上)
- 如何摆脱iOS 7.1.1中的layer.cornerRadius四舍五入的UIView中的薄边框?
- 有什么方法可以重置dequeueReusableAnnotationViewWithIdentifier中使用的队列吗?
- 无法自动select一个Xcode项目
- iOS:错误域= NSCocoaErrorDomain代码= 132001′ – 保存:在上下文中止’使用后台更新数据库coredata /推送通知
- iOS NSDictionary删除NULL值
- 以编程方式控制iOS数据连接
- 通过HealthKit中的HKWorkoutActivityType获取活动名称