web-dev-qa-db-ja.com

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];
}

しかし、これを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]);
}

ホストの証明書を許可するNSURLSessionのカテゴリも作成してみました。

#import "NSURLRequest+IgnoreSSL.h"

@implementation NSURLRequest (IgnoreSSL)

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

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

@end

これも役に立たないようです。


[〜#〜] edit [〜#〜]

返すようにこのメソッドを更新しました:

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

}

まだ何もしません。

30
random

私にとって、あなたの最初の例はうまく機能しています。次のコードで問題なくテストしました(サーバー証明書を許可するため、もちろん非常に安全ではありません)。

@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です。データのダウンロードを開始するには、SessionTestオブジェクトを作成し、startSessionメソッドを呼び出します。

@interface SessionTest : NSObject <NSURLSessionDelegate>

- (void) startSession;

@end
39
osanoj

問題の具体的な解決策を提案するのに十分な情報がありません。

主な要件は次のとおりです。

  • バックグラウンドタスクが必要なため、backgroundSessionConfiguration:を使用して適切なNSSessionオブジェクトを作成したことを確認してください。 バックグラウンドセッションを取得するには、このクラスファクトリメソッドの使用が必須です。

  • 別のプロセスのバックグラウンドで実行されるリクエストの場合、ploadおよびdownloadタスクのみがサポートされます。元のコードでは、dataタスクを使用していることに注意してください。

  • properlyがデリゲートメソッド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

サーバーの信頼評価を無効にすると、最初の例で試したように機能します。 これは開発のみに使用してください!

参照( https://developer.Apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html#//Apple_ref/doc/uid/TP40013509-SW44

1
CouchDeveloper