私は同じ問題に取り組んでいます.現在、私が見つけたのは、AFNetworkingに関するこの問題といくつかの助けだけです.
基本的にブロックを設定- (void)setTaskDidReceiveAuthenticationChallengeBlock:([long block variable type here])block;
しますAFURLSessionManager
証明書は p12 形式で保存されます。次の 2 行で、証明書のファイル名とパスフレーズを変更する必要があります。
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]];
CFStringRef パスワード = CFSTR("YOURPASSPHRASE");
このブロックを設定するコード全体は次のようになります。
AFHTTPRequestSerializer *reqSerializer = [AFHTTPRequestSerializer シリアライザー];
NSMutableURLRequest *リクエスト;
request = [reqSerializer requestWithMethod:メソッド URLString:[actionURL absoluteString] パラメータ:nil エラー:nil];
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:kallowInvalidSSLCertificate];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFHTTPResponseSerializer シリアライザー];
[操作 setSecurityPolicy:securityPolicy];
[操作 setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection *接続、NSURLAuthenticationChallenge *挑戦) {
if ([前のFailureCountに挑戦] > 0) {
//これは認証の失敗を引き起こします
[[チャレンジ送信者] cancelAuthenticationChallenge:チャレンジ];
NSLog(@"不正なユーザー名またはパスワード");
戻る;
}
//これはサーバー証明書をチェックしています
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType 結果。
//これは serverTrust オブジェクトを取得し、キーチェーンに対してチェックします
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
//証明書に対して無効なサーバーを無視する場合は、サーバーを受け入れるだけです
if (kallowsInvalidSSLCertificate) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
戻る;
} 他の場合 (結果 == kSecTrustResultProceed || 結果 == kSecTrustResultUnspecified) {
//信頼できるサーバーに対してこれをテストすると、毎回 kSecTrustResultUnspecified を取得しました。しかし、他の 2 つは信頼できるサーバーの説明と一致します。
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
戻る;
}
} そうでなければ ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
//これは、クライアント証明書の認証を処理します
/*
ここで行う必要があるのは、これを行うために証明書と ID を取得することです。
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:ID 証明書:myCerts 永続性:NSURLCredentialPersistencePermanent];
[[チャレンジ送信者] useCredential:credential forAuthenticationChallenge:challenge];
-installCertificate のコードを使用して、証明書を簡単にロードできます。
IDを取得することはより困難です。
.p12 ファイルから取得できますが、パスフレーズが必要です。
*/
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"]];
CFStringRef パスワード = CFSTR("YOURPASSPHRASE");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = {パスワード};
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL、キー、値、1、NULL、NULL);
CFArrayRef p12Items;
OSStatus 結果 = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);
if(result == noErr) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);
SecCertificateRef certRef;
SecIdentityCopyCertificate(identityApp, &certRef);
SecCertificateRef certArray[1] = { certRef };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(certRef);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp 証明書:(__bridge NSArray *)myCerts 永続性:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);
[[チャレンジ送信者] useCredential:credential forAuthenticationChallenge:challenge];
} そうしないと {
[[チャレンジ送信者] cancelAuthenticationChallenge:チャレンジ];
}
} そうでなければ ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) {
// ユーザー名とパスワードに基づく通常の認証用。これは、NTLM またはデフォルトの可能性があります。
/*
DAVCredentials *cred = _parentSession.credentials;
NSURLCredential *credential = [NSURLCredential credentialWithUser:cred.username パスワード:cred.password persistence:NSURLCredentialPersistenceForSession];
[[チャレンジ送信者] useCredential:credential forAuthenticationChallenge:challenge];
*/
NSLog(@"ベーシック認証");
} そうしないと {
//すべて失敗した場合、チャレンジをキャンセルします。
[[チャレンジ送信者] cancelAuthenticationChallenge:チャレンジ];
}
}];
[操作 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *操作、id responseObject) {
NSLog(@"成功");
} 失敗:^(AFHTTPRequestOperation *操作、NSError *エラー) {
NSLog(@"失敗");
}];
[[NSOperationQueue mainQueue] addOperation:操作];
このリンクを参照してください: https://github.com/AFNetworking/AFNetworking/issues/2316#issuecomment-115181437
私は今これを試しています。