具有自签名证书的NSURLSession +服务器

ran*_*dom 31 objective-c nsurlconnection ios ios7 nsurlsession

我有一个生产的应用程序以及具有自签名证书的开发服务器.

我正在尝试测试NSURLSession和后台下载,但似乎无法过去- (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];
}
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何使用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]);
}
Run Code Online (Sandbox Code Playgroud)

我还尝试创建一个类别NSURLSession,允许主机的任何证书:

#import "NSURLRequest+IgnoreSSL.h"

@implementation NSURLRequest (IgnoreSSL)

+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host {
    return YES;
}

+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host {}

@end
Run Code Online (Sandbox Code Playgroud)

这似乎也没有帮助.


编辑

我已更新此方法以返回:

- (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);

}
Run Code Online (Sandbox Code Playgroud)

哪个仍然无效.

osa*_*noj 40

对我来说,你的第一个例子是正常的.我已经使用以下代码测试没有问题(它当然非常不安全,因为它允许任何服务器证书).

@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
Run Code Online (Sandbox Code Playgroud)

更新:这是类接口,SessionTest类是NSURLSessionDataDelegate,启动数据下载后创建一个SessionTest对象并调用startSession方法.

@interface SessionTest : NSObject <NSURLSessionDelegate>

- (void) startSession;

@end
Run Code Online (Sandbox Code Playgroud)

  • 这在9.2上失败了 (2认同)
  • 我想为在这个帖子上绊脚的人添加一些信息.委托方法URLSession:task:didReceiveChallenge:CompletionHandler:授予对自签名(或过期)证书的信任,在重建开发应用程序时,它永远不会再被调用.这是因为对该证书的授权持久存储在〜/ Library/Cache/one中的应用程序缓存文件夹中. (2认同)