0

クライアント証明書を必要とするサーバーに接続しようとしています。したがって、このサーバーを参照するときに発生するイベントの通常の流れは、Web ブラウザー (Safari と Chrome の両方) がユーザーに証明書を選択して操作を再試行するように求めることです。

では、Cocoa プロジェクトに埋め込まれた WebView でこれを実現するにはどうすればよいでしょうか? これまでのところ、メソッドでエラーが発生していることを確認しましたdidFailProvisionalLoadWithError:

- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
    NSLog(@"webView:didFailProvisionalLoadWithError:forFrame:");
    NSLog(@"    error = %@", error);
}

エラーは確かにerror = Error Domain=NSURLErrorDomain Code=-1206 UserInfo=0x1006a8030 "The server “myserver.xxx” requires a client certificate.
ですが、ユーザーがキーチェーンから証明書を選択できるようにダイアログを表示するにはどうすればよいですか?

4

2 に答える 2

3

問題が解決しました。

WebViewコンポーネントの(既知の)問題が原因でした。AppleでDTSサポートチケットを開き、回避策を入手しました。

編集:これがDTSからの回避策です(3年前だったので、これがまだ有効かどうかはわかりません):

マグナスOK、私はこれを見る機会があり、何が起こっているのかを知っています。WebViewについて説明する前に、NSURLConnectionで使用されるデリゲートメソッドについて説明する必要があります。NSURLConnectionは、実際にネットからデータをロードするために使用される基盤となるAPIです。NSURLConnectionは、単一の認証デリゲートコールバック-connection:didReceiveAuthenticationChallenge:のサポートを開始し、その時点でサポートされていたさまざまな認証チャレンジ(ユーザー名/パスワードスタイルのチャレンジ)に合格しました。Mac OS X 10.6(およびiOS 3.0)では、NSURLConnectionが拡張され、TLS接続の2つの追加タイプの認証チャレンジをサポートします。oクライアントIDチャレンジ(NSURLAuthenticationMethodClientCertificate)、デリゲートに特定のTLS接続のクライアントIDを選択する機会を与えるoサーバー信頼チャレンジ(NSURLAuthenticationMethodServerTrust)、デリゲートに特定のTLS接続のサーバー信頼評価をオーバーライドする機会を与える互換性の理由から、これらのチャレンジに合格することはできませんでしたそのため、NSURLConnectionは、すべての状況でデリゲートに新しいデリゲートコールバック-connection:canAuthenticateAgainstProtectionSpace:を導入しました。これにより、デリゲートはこれらのチャレンジにオプトインできます。* * *では、これをアプリに戻しましょう。前述したように、WebViewはNSURLConnectionを使用し、接続ごとに接続デリゲートとして機能します。認証チャレンジをインターセプトし、それらをリソースロードデリゲートに渡します。WebViewは特別なことを何もしなくてもチャレンジを取得できるため、これは古い学校の認証チャレンジには問題なく機能します。ただし、デリゲートはこれらのチャレンジをオプトインする必要があるため、TLS接続認証のチャレンジでは失敗します。本当に必要なのは、「canAuthenticateAgainstProtectionSpace」認証チャレンジのWebViewバージョンです。さて、これは実際に実装されていることがわかります。WebViewのオープンソースを調べたところ、プライベートデリゲートコールバック-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:があり、これはまさにあなたが望むことを実行します。デリゲートはこれらの課題を選択する必要があるためです。本当に必要なのは、「canAuthenticateAgainstProtectionSpace」認証チャレンジのWebViewバージョンです。さて、これは実際に実装されていることがわかります。WebViewのオープンソースを調べたところ、プライベートデリゲートコールバック-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:があり、これはまさにあなたが望むことを実行します。デリゲートはこれらの課題を選択する必要があるためです。本当に必要なのは、「canAuthenticateAgainstProtectionSpace」認証チャレンジのWebViewバージョンです。さて、これは実際に実装されていることがわかります。WebViewのオープンソースを調べたところ、プライベートデリゲートコールバック-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:があり、これはまさにあなたが望むことを実行します。 http://www.opensource.apple.com/source/WebKit/WebKit-7533.20.25/mac/WebView/WebResourceLoadDelegatePrivate.h そのメソッドを実装する場合、クライアントID認証チャレンジにオプトインし、そのチャレンジに基づいて、ユーザーがIDを選択できるようにするユーザーインターフェイスを提示できます。私はあなたのテストアプリでこれをプロトタイプ化しました、そしてそれは魅力的に働きます。クライアントIDチャレンジを取得するために使用したコードは次のとおりです。-(BOOL)webView:(WebView *)sender resource:(id)identifier canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace forDataSource:(WebDataSource *)dataSource {NSLog(@ "%@ "、[protectionSpace authenticationMethod]); return [[protectionSpace authenticationMethod] isEqual:NSURLAuthenticationMethodClientCertificate]; }そしてこれに応答するために使用したコードは次のとおりです。-(void)webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource {NSLog(@ "didReceiveAuthenticationChallenge"); NSString * authenticationMethod=[[チャレンジ保護スペース]authenticationMethod]; NSLog(@ "authenticationMethod =%@"、authenticationMethod);

 [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; }

明らかに、実際のアプリでは、UIを表示する必要があります。次に、ユーザーがクライアントIDを選択したら、そのクレデンシャルを作成し(+ [NSURLCredential credentialWithIdentity:certificates:persistence:])、そのクレデンシャルをチャレンジに適用します。 (-useCredential:forAuthenticationChallenge:)。* * *では、ここからどこに進みますか?他に何をするかに関係なく、WebViewに対してバグを報告して、パブリックヘッダーに公開された-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:デリゲートコールバックを取得する必要があります。それは明白で、最も厄介な省略です。http://developer.apple.com/bugreporter/ バグを報告したら、このインシデントに関連付けることができるように、バグ番号を送ってください。それを超えると、今後の方向性はあまり明確ではありません。Mac以外のAppStoreアプリを作成している場合は、上記のように「canAuthenticateAgainstProtectionSpace」デリゲートコールバックを実装して、作業を続行することをお勧めします。OTOH、デリゲートコールバックを含むプライベートAPIの使用が厳しく禁止されているMac App Storeアプリを作成している場合、人生は非常にトリッキーになります。その場合はお知らせください。オプションについて話し合うことができます。共有してお楽しみください

于 2011-06-14T07:12:09.840 に答える
1

WebResourceLoadDelegate認証チャレンジ関連のデリゲート メソッドを設定して実装します。認証チャレンジを受信するとプロンプトが表示され、その時点で使用する証明書を提供できます。

ETA:NSURLCredentialに保存されている証明書からを作成する方法はclientSide.p12とおりです。

NSString *thePath = [[NSBundle mainBundle]
        pathForResource:@"clientside" ofType:@"p12"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;    
SecIdentityRef identity;
SecTrustRef trust;
extractIdentityAndTrust(inPKCS12Data, &identity, &trust);

SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate (identity, &certificate); 

const void *certs[] = {certificate};
CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);

NSURLCredential *credential = [NSURLCredential
        credentialWithIdentity:identity
        certificates:(NSArray*)certArray
        persistence:NSURLCredentialPersistencePermanent];

これは別の質問から来ています。この質問も役立つ場合があります。「nsurlcredential certificate」のグーグルでこれらを見つけました。

于 2011-04-18T22:08:59.337 に答える