私は困惑しています:私のアプリは、HTTPS用の自己署名証明書を使用するサーバーに接続する必要があり、クライアント側の認証が必要です。さらに悪いことに、私は実際にそのサーバーに接続するためのiOSメディアプレーヤーを必要とするので、私は手紙にAppleのinstructionこのために従っている:NSURLCredentialStorage setDefaultCredential:[NSURLSession sharedSession]のために動作しません
credential = [NSURLCredential credentialWithIdentity:identity certificates:certs persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:@"server.com"
port:0
protocol:NSURLProtectionSpaceHTTPS
realm:nil
authenticationMethod:NSURLAuthenticationMethodClientCertificate];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:space];
しかし、それだけでは動作しません。私は自分のNSURLSessionを設定し、URLSession使用している場合今
2016-06-13 08:22:37.767 TestiOSSSL[3172:870700] CFNetwork SSLHandshake failed (-9824 -> -9829)
2016-06-13 08:22:37.793 TestiOSSSL[3172:870700] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9829)
2016-06-13 08:22:37.815 TestiOSSSL[3172:870685] Done : Error Domain=NSURLErrorDomain Code=-1206 "The server “ server.com” requires a client certificate." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x13de519b0>, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9829, NSUnderlyingError=0x13de4f280 {Error Domain=kCFErrorDomainCFNetwork Code=-1206 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=1, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x13de519b0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9829, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9829, kCFStreamPropertySSLPeerCertificates=<CFArray 0x13dda0a70 [0x1a0dc2150]>{type = immutable, count = 2, values = (
0 : <cert(0x13dda4970) s: Server.com i: Localhost CA>
1 : <cert(0x13dda50d0) s: Localhost CA i: Localhost CA>
)}}}, NSErrorPeerCertificateChainKey=<CFArray 0x13dda0a70 [0x1a0dc2150]>{type = immutable, count = 2, values = (
0 : <cert(0x13dda4970) s: Server.com i: Localhost CA>
1 : <cert(0x13dda50d0) s: Localhost CA i: Localhost CA>
)}, NSLocalizedDescription=The server “server.com” requires a client certificate., NSErrorFailingURLKey=https://server.com/, NSErrorFailingURLStringKey=https://server.com/, NSErrorClientCertificateStateKey=1}
:didReceiveChallenge:completionHandlerを私が得るすべては、このエラーである
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://server.com"]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Done : %@", error ? error : @"OK");
}];
:だから私は、手動でサーバーに要求を実行しようとしました。コールバック:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
theSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
NSURLSessionDataTask *task = [theSession dataTaskWithURL:[NSURL URLWithString:@"https://server.com"]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Done : %@", error ? error : @"OK");
}];
、その後:
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
NSLog(@"Asking for credential");
NSURLCredential *conf = [session.configuration.URLCredentialStorage defaultCredentialForProtectionSpace:challenge.protectionSpace];
completionHandler(NSURLSessionAuthChallengeUseCredential, conf);
}
[session.configuration.URLCredentialStorage defaultCredentialForProtectionSpace:challenge.protectionSpace]を使用していることに注目してください。これは、NSURLSessionのデフォルト実装が認証チャレンジを取得したときに行うものです。
これは、この特定の接続で機能します。これは、資格証明がOKであり、デフォルトの資格証明としてデフォルトNSURLCredentialStorageに正しく登録されていることを証明します。
しかし、didReceiveChallenge:コールバックの周りをヒンティングするソリューションは、メディアプレーヤーが使用しているNSURLSessionを制御できないため、いいです。
私はCustomHTTPProtocolハックを試しましたが、どちらもうまくいきません。
提案がありますか?私はSOのすべての同様の記事を見てきましたが、私はこれのための解決策を見つけることができません。このpostは本当に近いですが、受け入れられた答えは私にとって意味をなさないものであり、明らかにAppleのドキュメンテーションと矛盾しています。
提案していただきありがとうございます。はい、私はsharedSessionで呼び出すようにしましたが、喜びはありません。いずれにしても、iOS MediaPlayerが自分のプロセスで実行されていないため、共有された資格情報ストレージを使用することは決してできません。別のプロセスに完全に分離され、アプリケーションと画面を共有するだけです。実際に働いていた唯一の解決策は、サーバーとしてメディアプレーヤーに配置されたアプリケーションにHTTPプロキシをセットアップし、受信したリクエストを実際のサーバーに転送して、独自の接続で資格情報を処理することでした。 Clunky :-( –
それはあなたがまだWebビューのものをやっている人にとっては問題です。もしあなたがまだAppleにバグを報告して、メディアプレーヤーに資格を与える方法を尋ねてください。何年もの間、繰り返し問題になってきました。私のウェブサイトの1つには、Safariの内蔵ビデオ再生が数年前に基本またはダイジェストの認証情報を渡すことができなかったという事実を回避するためのヒントがまだあります。私はバグを提出し、最終的にそれを修正しましたが、明らかにそれは彼らが多く考えている使用モデルではありません。認証が重要であることを知らせるバグを提出してください。 – dgatwood