2012-02-28 32 views
4

私は目的Cの新機能ですが、いくつかのWebコンテンツを読み込むUIWebViewを持つアプリケーションを開発しています。すべてのウェブページは認証のためのクライアント証明書を必要とし、私は露の日に苦労しています。 誰もがUIWebViewでそれを実装する方法を知っていますか?UIWebViewのクライアント証明書認証iOS

ありがとうございます!

+0

SFSafariViewController(Safariサービスフレームワーク)でiOSのIDを使用できるようになりました。 – smat88dd

答えて

8

UIWebViewの問題を回避するには、Webビューの要求の前に、クライアント証明書を使用してWebサイトルートの要求を行う必要があります。あなたはUIWebViewDelegateメソッドを使用することができます。

この後
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

、のUIWebViewは何の問題もなく、すべてを読み込むことができるようになります。

Objective-Cを初めてお使いの方は、Foundationフレームワークを初めてお使いの方もいらっしゃると思いますので、ここをクリックしてください。

これを解決するために、私は既にプロジェクトに組み込まれているので、私はASIHTTPRequestを使用しました。しかし、あなたはNSURLConnectionを使用してNSURLConnectionDelegate方法でロジックを行うことができます:私は「

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 

    SecIdentityRef identity = NULL; 
    SecTrustRef trust  = NULL; 
    NSData *PKCS12Data  = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.cert" ofType:@"pfx"]]; 

    [self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data]; 

    NSURL *serverUrl    = [NSURL URLWithString:URL_SECURE_SERVER]; 
    ASIHTTPRequest *firstRequest = [ASIHTTPRequest requestWithURL:serverUrl]; 

    [firstRequest setValidatesSecureCertificate:NO]; 
    [firstRequest setClientCertificateIdentity:identity]; 
    [firstRequest startSynchronous]; 

    return YES; 
} 

:だから

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

、ここでは前のUIWebView要求にASIHTTPRequestにクライアント証明書を提供するために、私のコードですUIWebViewにロードを開始させる前に、要求を同期的に送信して完了を確認します。

は私がある証明書、身元から取得するメソッドを使用します。あなたのSecIdentityRefとを取得する。ここ

- (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data 
{ 
    OSStatus securityError   = errSecSuccess; 
    NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"mobigate" forKey:(id)kSecImportExportPassphrase]; 

    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    securityError  = SecPKCS12Import((CFDataRef)inPKCS12Data,(CFDictionaryRef)optionsDictionary,&items); 

    if (securityError == 0) { 
    CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0); 
    const void *tempIdentity   = NULL; 

    tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity); 
    *outIdentity = (SecIdentityRef)tempIdentity; 

    const void *tempTrust = NULL; 

    tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust); 
    *outTrust = (SecTrustRef)tempTrust; 

    } 
    else { 
    NSLog(@"Failed with error code %d",(int)securityError); 
    return NO; 
    } 

    return YES; 
} 

同じ技術を、代わりにASIHTTPRequest

  • のNSURLConnectionを使用して、 SecCertificateRef
  • これらの情報でNSURLCredentialを作成する
  • このNSURLCredentialをth番目の[チャレンジ送信者]に返送するE接続:didReceiveAuthenticationChallenge:メソッド

NSURLConnectionを持つ証明書を使用するには、あなたがNSURLConnectionDelegateメソッドを実装する必要があります。この方法では

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

を、NSURLConnectionはそれが挑戦を受けたことを語っています。あなたは、あなたがあなたのNSURLCredentialを作成し、[チャレンジ送信者]

に返送するNSURLCredentialを作成する必要があります:

+ (NSURLCredential *)credentialWithIdentity:(SecIdentityRef)identity certificates:(NSArray *)certArray persistence:(NSURLCredentialPersistence)persistence 
{ 

    NSString *certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"]; 
    NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath]; 

    SecIdentityRef myIdentity; // ??? 

    SecCertificateRef myCert = SecCertificateCreateWithData(NULL, (CFDataRef)certData); 
    [certData release]; 
    SecCertificateRef certArray[1] = { myCert }; 
    CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL); 
    CFRelease(myCert); 
    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity 
           certificates:(NSArray *)myCerts 
           persistence:NSURLCredentialPersistencePermanent]; 
    CFRelease(myCerts); 
} 

そして最後に[チャレンジ送信者]に

- (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

でそれを使用します

必要なものがすべてあるはずです。がんばろう。

+0

ありがとうございます、私はそれを調べて、私の所見を更新します。 –

+0

私はそれをチェックして、私はまだNSURLConnectionDelegate関数で苦労しています:didReceiveAuthenticationChallenge ...あなたはASIHTTPRequestクラスの代わりにそれを使用する方法を詳しく説明できますか? –

+0

あなたはどんなところで苦労していますか? – teriiehina

関連する問題