【发布时间】:2016-01-18 05:37:30
【问题描述】:
我正在尝试使用 NSUrlsession 通过 SSL (.p12) 客户端证书连接服务器。我已成功使用 NSURLConnection 连接到同一台服务器。 但是使用 NSURLsession 我得到“取消”错误。 以下是我的设置:
-(void) loadDataFromServer{
NSURL *url=[NSURL URLWithString:@"https://domain:port/serviceName/method/parameter"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionConfiguration *sessionConfig =[NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:Nil];
NSURLSessionDataTask *downloadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Data :%@",data);
NSLog(@"Response :%@",response);
NSLog(@"Error :%@",error);
if (!error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 200) {
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(@"Data :%@",json);
}
}
}];
[downloadTask resume];}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{
NSURLCredential *newCredential;
NSString *authenticationMethod = challenge.protectionSpace.authenticationMethod;
if ([authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
// Replace the user login and password as appropriate.
newCredential = [NSURLCredential credentialWithUser:@"UserName" password:@"Password" persistence:NSURLCredentialPersistenceNone];
} else if ([authenticationMethod isEqualToString:@"NSURLAuthenticationMethodClientCertificate"]) {
// load cert
NSString *path = [[NSBundle mainBundle] pathForResource:@"certificateName" ofType:@"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
OSStatus status = extractIdentityAndTrustCorpInv(inP12data, &myIdentity, &myTrust);
if (status == 0) {
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
newCredential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistenceForSession];
}
}
[[challenge sender]useCredential:newCredential forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential,newCredential);
}
#pragma mark -
#pragma mark Identity and Trust
- OSStatus extractIdentityAndTrustCorpInv(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("CertPassword");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}
并且 NSLog 给出以下错误:
错误 :Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://domain:port/serviceName/method/parameter, NSErrorFailingURLStringKey=https://domain:port/serviceName/method/parameter, NSLocalizedDescription=cancelled}
任何帮助将不胜感激。
【问题讨论】:
-
这听起来与in this related question 完全相同的问题(我很想将其标记为重复)
-
不是骗子。 ATS 对 NSURLConnection 和 NSURLSession 的影响是一样的。
标签: objective-c authentication ssl-certificate ios9 nsurlsession