[Original] NSURLSession HTTPS Mutual Authentication, nsurlsessionmutual
1. Introduce the <NSURLSessionDelegate> Protocol
2. login verification request
-(void)authenticate{ NSURL *url = [NSURL URLWithString:authAddress]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"GET"; NSString *userString = @"name:password"; NSData *userData = [userString dataUsingEncoding:NSUTF8StringEncoding]; NSString *base64String = [userData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; [request setValue:[NSString stringWithFormat:@"Basic %@",base64String] forHTTPHeaderField:@"Authorization"]; NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { }]; [task resume];}
3. NSURLSessionDelegate callback
#pragma mark -- NSURLSessionDelegate- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])//Client Authentication { NSURLCredential *credential = [NSURLCredential credentialWithUser:@"name" password:@"password" persistence:NSURLCredentialPersistenceForSession]; completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])//Server Authentication { SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0); NSData *serverData = (__bridge_transfer NSData*)SecCertificateCopyData(serverCertificate); NSData *localData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"cer"]]; if ((!localData) || [serverData isEqualToData:localData]) { NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } else { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil); } } else { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil); }}
Note: NSURLAuthenticationMethodClientCertificate is used for client certificate verification. If you have a p12 certificate, use this certificate for authentication. For more information, see this article. NSURLAuthenticationMethodServerTrust is used for server verification, we need to compare the certificate data obtained by serverTrust, The Challenge returned by the Local Certificate with the server. If it is determined to be the same certificate, it will respond to the challenge. Note that, the Protocol callback will trigger two verification challenges. The verification will be canceled if there are other types of challenges.
If you have good experience, I hope you can share it with me ~ I am also learning